	/*
pcam message handler.
*/

#include "includes_fw.h"
#include "config_fw.h"
#include "mmp_lib.h"
#include "os_wrap.h"
#include "lib_retina.h"

#include "mmpf_pll.h"

#include "pcam_msg.h"
#include "pcam_handler.h"
#include "mmps_display.h"
#include "mmps_sensor.h"
#include "mmpf_system.h"
#include "mmpd_system.h"
#include "mmps_3gprecd.h"
#include "mmp_reg_gbl.h"
#include "mmp_reg_gpio.h"
#include "mmpf_sensor.h"
//#include "sensor_ctl.h"
//#include "3A_ctl.h" //ZDW_BARCODE
#include "mmpf_usbvend.h"
#include "mmpf_usbpccam.h"
#include "mmpf_audio_ctl.h"
#include "isp_if.h"
#include "mmps_usb.h"
#include "mmpf_scaler.h"
#include "mmp_reg_vif.h"
#include "mmp_reg_scaler.h"
#include "mmp_reg_audio.h"
#include "mmpf_usbextrn.h"
#include "mmpf_usb_h264.h"
#include "mmpf_usbuvc.h"
#include "mmpf_usbuac.h"
#include "mmpf_encapi.h"
#include "lib_retina.h"
#include "mmpf_i2cm.h"

#include "mmpf_sif.h"
#include "mmpf_sf.h"
#include "mmp_reg_sif.h"
#include "mmpf_h264enc.h"
#include "mmpf_mp4venc.h"
#include "hdm_ctl.h"
#include "mmpf_rawproc.h"
#include "pcam_dfu.h"
#include "mmpf_sif.h"
#include "mmpf_usbuvch264.h"
#include "pcam_usb.h"
#include "mmpf_3gpmgr.h"
#include "mmpf_timer.h"
#include "mmpf_vif.h"
#if (SUPPORT_CNXT_FW_DOWNLOADING_RAM)
#include "cxcodecapi.h" 
#endif

#if UVC_SETTING_LOAD_FROM_FLASH
#include "mmpf_usbdescr.h"
#endif

#include "customer.h"
#if AUDEXT_DAC==ADC3101 
#include "ADC3101.h"
#endif
#if AUDEXT_DAC==AIC3254 
#include "AIC3254.h"
#endif
#if (AUDEXT_DAC==WM8973)
#include "wm8973.h"
#endif


#if (SUPPORT_OSD_FUNC)
#include "pCam_osd_api.h"
#endif
#if (SUPPORT_H264MV_MD)
#include "motion_dtc.h"
#endif
#if SUPPORT_AIT845x_MD
#include "md.h"
#endif

#define _DBGMSG_	(0)	//debug usage


#if SKYPE_MODE_B
extern MMP_UBYTE gbSkypeMode;
#endif

extern MMP_UBYTE gbUVCPara[];

extern MMPF_SENSOR_FUNCTION *gsSensorFunction ;
extern MMPF_OS_FLAGID PCAM_Flag ;
extern MMPS_DISPLAY_OUTPUTPANEL  gsCurrentDisplay;// = MMPS_DISPLAY_MAIN_LCD;

#if SUPPORT_UAC
extern MMP_UBYTE gbADCDigitalGain ;
extern MMP_UBYTE gbADCAnalogGain  ;
extern MMP_UBYTE gbADCBoost  ;
extern MMP_UBYTE  gbMute;

//extern MMP_BOOL gbVideoEncQualityCustom;
//extern MMP_UBYTE gbCustomQp;
//extern MMP_ULONG glCustomTargetSizePerFrame;
extern MMP_UBYTE gbAudioMode;
static MMP_UBYTE gbOrigADCDigitalGain   ;
#endif

MMP_USHORT m_usResolType;
MMP_USHORT m_usVideoQuality;
MMP_UBYTE gbCurrentSensor = MAIN_SENSOR; //SUB_SENSOR ;
MMP_UBYTE gbSwitchSensor = MAIN_SENSOR; //SUB_SENSOR ;
MMP_UBYTE gbTableUsed = CALI_TABLE_AUTO;
MMP_UBYTE gbTestCaliTable = CALI_TABLE_UNDEFINED; //Set true to force apply current cali data from the host. Typically used while calibrating.
MMP_UBYTE gbDevicePowerSavingStatus = 1;
MMPS_3GPRECD_VIDEO_FORMAT m_VideoFmt = MMPS_3GPRECD_VIDEO_FORMAT_OTHERS ;
MMP_UBYTE glAudioEnable = FALSE;
#if (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778) 
MMP_UBYTE gbAudioProcBypassFlag = 0;
#endif
MMP_UBYTE glAudioCodecInit = FALSE;
MMP_USHORT gsVideoEncodeFPS = 30; 

MMP_UBYTE gbBOOST_DB = 10;  // digital gain, base is 10

#if (SUPPORT_OSD_FUNC) 
#if (MOVE_OSD_USING_DMA)
MMP_ULONG glOSDStartBufAddr, glOSDBufferSize;
#endif
extern MMP_USHORT m_usOsdStartXOffset, m_usOsdStartYoffset;
extern MMP_ULONG OSD_CurrentW[],OSD_CurrentH[];
extern MMP_ULONG OSD_FontW[],OSD_FontH[];
extern MMP_UBYTE gbOSDForeColorY;
extern MMP_USHORT gsOSDForeColorUV;
extern MMP_UBYTE gbOSDBackColorY;
extern MMP_USHORT gsOSDBackColorUV;
#endif

//static MMP_BOOL gbADCMute ;
static PCAM_USB_CTX pCamCtx ;
static PCAM_ASYNC_VC_CFG pCamVCCfg ;

//static MMP_UBYTE gbOrigADCAnalogGain  ;
//static MMP_UBYTE gbOrigADCBoost ;
//static void MMPF_Init_DefaultClock(void);
static MMP_USHORT PCAM2MMP_Get_Quality(PCAM_USB_INFO *pcam_info) ;
static MMP_USHORT PCAM2MMP_Get_Resolution(PCAM_USB_INFO *pcam_info);
static MMPS_3GPRECD_VIDEO_FORMAT PCAM2MMP_Get_VideoFormat(PCAM_USB_INFO *pcam_info);
#if SUPPORT_UAC
static MMPS_3GPRECD_AUDIO_FORMAT PCAM2MMP_Get_AudioFormat(PCAM_USB_INFO *pcam_info);
#endif
static MMP_USHORT PCAM2MMP_Get_DebandMode(PCAM_USB_INFO *pcam_info);
static void MMPF_Init_DefGain(void) ;
#if (CUSTOMER != ASU)
static MMP_SHORT PCAM2MMP_Normalize_Value(MMP_USHORT val) ;
//static MMP_SHORT PCAM2MMP_Normalize_EV(MMP_SHORT val);
#endif
static MMP_SHORT PCAM2MMP_Normalize_HUE(MMP_SHORT val);
static MMP_USHORT PCAM2MMP_Normalize_Gain(MMP_USHORT val);

MMP_ULONG glEndOfH264SramAddr = 0 ;
#if (BIND_SENSOR_MT9D111)
    MMP_SHORT mt9d111_inited = 0;
#endif

void MMPF_PCAM_StartUSB(void) ;
//void GPIO_InputPinControl(MMP_UBYTE num, MMP_UBYTE pad_status, MMP_UBYTE int_dir);
void GPIO_OutputControl(MMP_UBYTE num, MMP_UBYTE status);

#if (AUDEXT_DAC == WM8973)
	extern void	InitExtLineIn(void);
	extern void PowerUpExtLinIn(MMP_ULONG samplerate);
	extern MMP_ERR MMPC_AudioExtCodec_SetSampleRate(MMP_ULONG ulSamplerate);
	extern MMP_ERR MMPC_AudioExtCodec_SetMute(MMP_BOOL bMute);
	extern MMP_ERR MMPC_AudioExtCodec_SetRecordVolume(MMP_LONG dB);
#endif
#if (AUDEXT_DAC == WM8960)
extern void	InitExtLineIn(void);
extern void PowerUpExtLinIn(MMP_ULONG samplerate);
extern void PowerDownExtDAC(void);
extern MMP_ERR MMPC_AudioExtCodec_SetSampleRate(MMP_ULONG ulSamplerate);
extern MMP_ERR MMPC_AudioExtCodec_SetMute(MMP_BOOL bMute);
extern MMP_ERR MMPC_AudioExtCodec_SetRecordVolume(MMP_LONG dB);
#endif
//
// Log the async. mode settings for pCam handler to call async. mode function
//
MMP_USHORT PCAM_SetAsyncVideoControl(MMP_UBYTE bOriginator,MMP_UBYTE bSelector,MMP_UBYTE bAttribute,MMP_UBYTE bValUnit)
{
    pCamVCCfg.pCamEnableAsyncMode = 1; // Enable Async mode or not
    pCamVCCfg.pCamOriginator = bOriginator;
    pCamVCCfg.pCamSelector = bSelector;
    pCamVCCfg.pCamAttribute = bAttribute;
    pCamVCCfg.pCamValUnit = bValUnit ;
    return PCAM_ERROR_NONE ;
}

#if SUPPORT_UAC

static MMP_USHORT PCAM2MMP_Get_AudioInPath(PCAM_AUDIO_CFG *pcam_audio);
static MMPF_AUDIO_LINEIN_CHANNEL PCAM2MMP_Get_AudioInChannel(PCAM_AUDIO_CFG *pcam_info);

#if(MicSource == MicInPathI2S)
static void MMPF_Init_ExteralDac(MMP_ULONG samplerate);
#endif

/*
Wolfson DAC W8737
*/
#if AUDEXT_DAC==WM8737 
static void MMPF_InitWM8737(MMP_ULONG samplerate);
static void MMPF_PowerUpWM8737(MMP_USHORT);
static void MMPF_PowerDownWM8737(void);
void MMPF_WM8737VolumeControl(MMP_UBYTE volume);
/* Gason@20100730, Separate WM8737 function to three function, init , power up and power down*/
static MMPF_I2CM_ATTRIBUTE m_WM8737_I2cmAttribute = {MMPF_I2CM_ID_0, 0x1A, 8, 8, 0, MMP_FALSE, MMP_FALSE, MMP_FALSE, MMP_FALSE, 0, 0, 0, MMPF_I2CM_SPEED_HW_400K, NULL, NULL};
#endif
/*
Conexant ADC CX20709
*/
#if (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778) 
static void MMPF_InitCX20709(MMP_ULONG samplerate);
static MMP_ERR MMPF_CX20709_Wait_NewC_Done(void);
static MMP_ERR MMPF_CX20709_Set_SampleRate(MMP_ULONG sr); 
static void MMPF_CX20709_Set_Bypass_Mode(MMP_UBYTE bypass_on); 
static void MMPF_PowerUpCX20709(void);
static void MMPF_PowerDownCX20709(void);
static void MMPF_CX20709VolumeControl(MMP_UBYTE volume);
static void MMPF_CX20709_SetMute(MMP_UBYTE enable);
#endif

void PCAM_USB_AudioSetMode(pcam_msg_t *msg);

#if(MicSource == MicInPathI2S)
static void MMPF_Init_ExteralDac(MMP_ULONG samplerate)
{
// Audio IN use I2C interface.
#if (AUDEXT_DAC==WM8737)
    MMPF_InitWM8737(samplerate);
#endif

#if (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778) 
    MMPF_InitCX20709(samplerate);
#endif

#if (AUDEXT_DAC==WM8973) || (AUDEXT_DAC==WM8750) || (AUDEXT_DAC==WM8960)
	InitExtLineIn();
#endif

#if (AUDEXT_DAC == ADC3101)
    MMPF_InitTLV320ADC3101(samplerate);
#endif

}
#endif

#endif  // #if SUPPORT_UAC

/*
static void MMPF_Init_DefaultClock(void)
{
//extern void MMPF_SaveDefClock(MMP_ULONG clk) ;
#if (CHIP==P_V2)||(CHIP == VSN_V2)
    // TBD
#endif
                               
}
*/

extern MMP_UBYTE    os_created_task_prio[];
extern MMP_UBYTE    os_created_tasks ;
//extern void dbg_printf(unsigned long level, char *fmt, ...);
void MMPF_PCAM_WaitTaskIdle(MMP_UBYTE wait_flag)
{
    OS_TCB task;
    MMP_UBYTE err ,i ,prio;
    for (i=0;i<os_created_tasks;i++) {
        prio = os_created_task_prio[i] ;
        err = OSTaskQuery(prio,&task) ;
        if(err==OS_NO_ERR) {
            if(task.OSTCBPrio != OSTCBCur->OSTCBPrio) {
                if(task.OSTCBStat!= wait_flag) {
                    //dbg_printf(0,"@ Task Id:%d not idle\r\n",task.OSTCBPrio);
                    i = 0 ;
                    MMPF_OS_Sleep(1);
                } 
            }
        } else {
	            dbg_printf(0,"@ Task Id:%d Err:%d\r\n",task.OSTCBPrio,err);
        }
    } 
    dbg_printf(0,"Tasks Idle,enter sleep\r\n");  
}

// Wait all task suspend then start usb enum.
extern void MMPF_SetUSBChangeMode(unsigned char mode);
void MMPF_PCAM_StartUSB(void)
{
extern MMP_UBYTE gbPowerSavingAtBoot;
#if USB_ENUM_AT_TASK_SUSPEND==1
  //  MMP_ULONG cpu_sr;
    
    OS_TCB task ;
    MMP_UBYTE err ,i ,prio;
    for (i=0;i<os_created_tasks;i++) {
        prio = os_created_task_prio[i] ;
    #if (WATCHDOG_RESET_EN == 1)
        if( (prio!=TASK_PCAM_PRIO)&& (prio!=(OS_LOWEST_PRIO - 2)))
    #elif SUPPORT_AIT845x_MD
        if((prio!=TASK_PCAM_PRIO)&&(prio!=TASK_AIT845xMD_PRIO))
    #elif UART_RXINT_MODE_EN
        if((prio!=TASK_PCAM_PRIO)&&(prio!=TASK_CE_JOB_DISPATCH_PRIO))
    #else
        if(prio!=TASK_PCAM_PRIO)
    #endif
        {
            err = OSTaskQuery(prio,&task);
            if(err==OS_NO_ERR) {
                if(task.OSTCBStat == OS_STAT_RDY ) {
                    RTNA_DBG_Str(3,"@ Task #");
                    RTNA_DBG_Byte(3,prio);
                    RTNA_DBG_Str(3," not pend...\r\n");
                    i = 0 ;
                    MMPF_OS_Sleep(1);
                }
            } else {
                RTNA_DBG_Str(3,"@ Task # Err\r\n");
            }
        }
    }
#endif
    RTNA_DBG_Str(3,"!Start USB Enum...\r\n");
// Disable Task running when USB start to enum
    TASK_CRITICAL(
        MMPF_SetUSBChangeMode(MMPS_USB_MSDC_MODE);
        if(gbPowerSavingAtBoot==0) {
            //MMPF_SYS_EnterPSMode(2);
            gbPowerSavingAtBoot = 1 ;
        }
    )
}

static void MMPF_Init_DefGain(void)
{
#if SUPPORT_UAC
    //gbOrigADCBoost = gbADCBoost ;
    //gbOrigADCAnalogGain = gbADCAnalogGain;
    gbOrigADCDigitalGain = gbADCDigitalGain;    
#endif
}

#if (IQ_SETTING_LOAD_FROM_FLASH)
extern MMP_UBYTE   gbBandFilter;
MMP_UBYTE gbIQ_Setting_Buffer[0x1000];

static void MMPF_PCAM_Init_IQ_Setting(MMP_ULONG iq_setting_addr)
{
    //MMP_UBYTE	ubManufacturerID;
    //MMP_USHORT	usDeviceID;
    MMP_UBYTE	*ptr;

    RTNA_DBG_Str3("MMPF_PCAM_Init_IQ_Setting() start...\r\n");

	//MMPF_SIF_Init();
    MMPF_SF_SetTmpAddr((MMP_ULONG)SIF_BUFFER_START);
    MMPF_SF_InitialInterface();
    if (MMPF_SF_Reset()) {
#if EN_DBGLOG_FOR_FLASH
        RTNA_DBG_Str(0, "\r\nSIF init error !!\r\n");
#endif
    }

    RTNA_DBG_Str3("  IQ_SETTING_ADDR_IN_FLASH = ");
    RTNA_DBG_Long3(IQ_SETTING_ADDR_IN_FLASH);
    RTNA_DBG_Str3("\r\n");
    RTNA_DBG_Str3("  iq_setting_addr = ");
    RTNA_DBG_Long3(iq_setting_addr);
    RTNA_DBG_Str3("\r\n");

#if 1  // read IQ table from serial flash
	MMPF_SF_ReadData(IQ_SETTING_ADDR_IN_FLASH, iq_setting_addr, IQ_SETTING_MAX_SIZE);  // read 256 bytes IQ table into DRAM buffer
    RTNA_DBG_Str3("  iq_setting_valid_flag = ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_setting_addr));
    RTNA_DBG_Str3("\r\n");
    
    if(*(MMP_UBYTE *)(iq_setting_addr) == 0x55){  // valid IQ setting
    
        RTNA_DBG_Str3("  iq_setting_data = ");
        RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_setting_addr));
        RTNA_DBG_Str3(" : ");
        RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_setting_addr+1));
        RTNA_DBG_Str3(" : ");
        RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_setting_addr+2));
        RTNA_DBG_Str3(" : ");
        RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_setting_addr+3));
        RTNA_DBG_Str3("\r\n");
        
        gbBandFilter = *(MMP_UBYTE *)(iq_setting_addr+1+BANDFILTER_OFFSET);
        
    }
    else{
        RTNA_DBG_Str3(" ### IQ setting in Flash is invalid ###\r\n");
        // load default IQ table
        //MEMCPY((MMP_UBYTE *)iq_setting_addr, (MMP_UBYTE *)&Sensor_IQ_CompressedText[0], IQ_TABLE_MAX_SIZE);

    #if (DEFAULT_FLICKER_MODE == FLICKER_60HZ)
        gbBandFilter = BAND_60HZ;
    #elif (DEFAULT_FLICKER_MODE == FLICKER_50HZ)
        gbBandFilter = BAND_50HZ;
	#else
		gbBandFilter = BAND_DISABLE;
    #endif
    }

#else  // test load IQ table from FW code  
    #if (DEFAULT_FLICKER_MODE == FLICKER_60HZ)
        gbBandFilter = BAND_60HZ;
    #elif (DEFAULT_FLICKER_MODE == FLICKER_50HZ)
        gbBandFilter = BAND_50HZ;
	#else
		gbBandFilter = BAND_DISABLE;
    #endif        

#endif

    RTNA_DBG_Str3("MMPF_PCAM_Init_IQ_Setting() end...\r\n");

}

void MMPF_PCAM_Update_IQ_Setting(MMP_ULONG iq_setting_offset, MMP_ULONG cur_val, MMP_ULONG len)
{
    //MMP_UBYTE	ubManufacturerID;
    //MMP_USHORT	usDeviceID;
    MMP_UBYTE	*ptr;
    MMP_ULONG   read_sector_no, table_offset, i;

    RTNA_DBG_Str3("MMPF_PCAM_Update_IQ_Setting() start...\r\n");

	//MMPF_SIF_Init();
    MMPF_SF_SetTmpAddr((MMP_ULONG)SIF_BUFFER_START);
    MMPF_SF_InitialInterface();
    if (MMPF_SF_Reset()) {
#if EN_DBGLOG_FOR_FLASH
        RTNA_DBG_Str(0, "\r\nSIF init error !!\r\n");
#endif
    }

    read_sector_no = (MMP_ULONG)((IQ_SETTING_ADDR_IN_FLASH / 0x1000) * 0x1000);
    table_offset = IQ_SETTING_ADDR_IN_FLASH-read_sector_no;
    // read sector to buffer
    MMPF_SF_ReadData(read_sector_no, (MMP_ULONG)&gbIQ_Setting_Buffer[0], 0x1000);
	
	gbIQ_Setting_Buffer[table_offset] = 0x55;  // write valid flag to active the table
	table_offset += 1;
	
    if(len > 4) {
        ptr = (MMP_UBYTE *)cur_val;
    	for(i = 0;i < len; i++){
        	gbIQ_Setting_Buffer[table_offset + iq_setting_offset + i ] = *(ptr+i);
        }
    }
    else{
        ptr = (MMP_UBYTE *)&cur_val;
    	for(i = 0;i < len; i++){
        	gbIQ_Setting_Buffer[table_offset + iq_setting_offset + i ] = *(ptr+i);
        }
    }

    //write sector to Flash
    MMPF_SIF_WriteData(read_sector_no, (MMP_ULONG)&gbIQ_Setting_Buffer[0], 0x1000);

    RTNA_DBG_Str3("MMPF_PCAM_Update_IQ_Setting() end...\r\n");

}

#endif

#if (IQ_TABLE_LOAD_FROM_FLASH)
//extern const ISP_UINT8 Sensor_IQ_CompressedText[];
static void MMPF_PCAM_Init_IQ_Table(MMP_ULONG iq_tbl_addr, MMP_UBYTE iq_tbl_id)
{
    //MMP_UBYTE	ubManufacturerID;
    //MMP_USHORT	usDeviceID;
    //MMP_UBYTE	*ptr;
    MMP_ULONG	tbl_flash_addr;

    RTNA_DBG_Str3("MMPF_PCAM_Init_IQ_Table() start...\r\n");

	//MMPF_SIF_Init();
    if (USB_ResetFlash()) {
        RTNA_DBG_Str(0, "\r\nSIF init error !!\r\n");
    }
    
#if SUPPORT_SWITCH_CAMERA
	tbl_flash_addr = ((gbSwitchSensor==MAIN_SENSOR)?IQ_TABLE_ADDR_IN_FLASH:IQ_TABLE2_ADDR_IN_FLASH);
#else
	tbl_flash_addr = ((iq_tbl_id==MAIN_SENSOR)?IQ_TABLE_ADDR_IN_FLASH:IQ_TABLE2_ADDR_IN_FLASH);
#endif
	
	dbg_printf(3, "  IQ_TABLE_ADDR_IN_FLASH = %08X\r\n", tbl_flash_addr);
    //RTNA_DBG_Str3("  iq_tbl_addr = ");
    //RTNA_DBG_Long3(iq_tbl_addr);
    //RTNA_DBG_Str3("\r\n");
	
#if 1  // bossino read IQ table from serial flash
	//MMPF_SF_ReadData(tbl_flash_addr, iq_tbl_addr, IQ_TABLE_MAX_SIZE); //older IQ tool w/o header
	MMPF_SF_ReadData((tbl_flash_addr+sizeof(XU_IQ_GAMMA_TABLE_HEADER)), iq_tbl_addr, IQ_TABLE_MAX_SIZE);  //read 12KB IQ table into DRAM buffer
    //RTNA_DBG_Str3("  iq_table_valid_flag = ");
    //RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr));
    //RTNA_DBG_Str3("\r\n");

    #if 0//debug
    {
        unsigned char nIdx;
        for(nIdx=0; nIdx<20; nIdx++) {
            RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr+nIdx));
            RTNA_DBG_Str3(" ");
        }
        RTNA_DBG_Str3("\r\n");
		if(iq_tbl_id == MAIN_SENSOR)
		{
	        for(nIdx=0; nIdx<20; nIdx++) {
	            RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr+0x18D9+nIdx));
	            RTNA_DBG_Str3(" ");
	        }
		}else if (iq_tbl_id == SUB_SENSOR)
		{
	        for(nIdx=0; nIdx<20; nIdx++) {
	            RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr+0x1FCB+nIdx));
	            RTNA_DBG_Str3(" ");
	        }
		}
        RTNA_DBG_Str3("\r\n");
    }
    #endif //debug

#elif 1  // read IQ table from serial flash

	MMPF_SF_ReadData(IQ_TABLE_ADDR_IN_FLASH, iq_tbl_addr, 256);  // read 16KB IQ table into DRAM buffer
    RTNA_DBG_Str3("  iq_table_valid_flag = ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr));
    RTNA_DBG_Str3("\r\n");
    
    if(*(MMP_UBYTE *)(iq_tbl_addr) == 0x55){  // valid IQ table
    
	    MMPF_SF_ReadData(IQ_TABLE_ADDR_IN_FLASH + 1, iq_tbl_addr, IQ_TABLE_MAX_SIZE-1);  // read 16KB IQ table into DRAM buffer
        RTNA_DBG_Str3("  iq_tbl_data = ");
        RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr));
        RTNA_DBG_Str3(" : ");
        RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr+1));
        RTNA_DBG_Str3(" : ");
        RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr+2));
        RTNA_DBG_Str3(" : ");
        RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr+3));
        RTNA_DBG_Str3("\r\n");
    }
    else{
        RTNA_DBG_Str3(" ### IQ table in Flash is invalid ###\r\n");
        // load default IQ table
        MEMCPY((MMP_UBYTE *)iq_tbl_addr, (MMP_UBYTE *)&Sensor_IQ_CompressedText[0], IQ_TABLE_MAX_SIZE);
    }

#else  // test load IQ table from FW code  

	MMPF_SF_ReadData(IQ_TABLE_ADDR_IN_FLASH, iq_tbl_addr, IQ_TABLE_MAX_SIZE);  // read 16KB IQ table into DRAM buffer
    RTNA_DBG_Str3("  iq_tbl_data = ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr));
    RTNA_DBG_Str3(" : ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr+1));
    RTNA_DBG_Str3(" : ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr+2));
    RTNA_DBG_Str3(" : ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(iq_tbl_addr+3));
    RTNA_DBG_Str3("\r\n");

    MEMCPY((MMP_UBYTE *)iq_tbl_addr, (MMP_UBYTE *)&Sensor_IQ_CompressedText[0], IQ_TABLE_MAX_SIZE);
#endif

    RTNA_DBG_Str3("MMPF_PCAM_Init_IQ_Table() end...\r\n");

}
#endif


#if (UVC_SETTING_LOAD_FROM_FLASH)
MMP_USHORT  gsVIDPID_HEAD_OFFSET;
MMP_USHORT  gsSNSTRING_HEAD_OFFSET;

MMP_USHORT PCAM_GetCustomerDataTag(MMP_USHORT *pTagID, MMP_USHORT *pTagLength, MMP_UBYTE **ppImgAddr, MMP_ULONG length)
{
    MMP_ULONG i;
    i = 0;

    while(*(*ppImgAddr + i) != 0xEE && i < length)
        i++;

    if(i >= length)
        return 1 ; // 1 : error

    *ppImgAddr = *ppImgAddr + i;

    *pTagID = (**ppImgAddr << 8) + *(*ppImgAddr + 1);
    if(*pTagID >= 0xEE80) {
        *pTagLength = 0;
    } else {
        *pTagLength = *(*ppImgAddr + 2) + (*(*ppImgAddr + 3) << 8);
    }
    return 0;
}

MMP_ULONG PCAM_Search_CustomerData_Offset(MMP_UBYTE *tbl, MMP_LONG len, MMP_USHORT tag)
{
    MMP_USHORT tagID = 0,tagLength = 0 ;
    MMP_UBYTE  *tblBuf = (MMP_UBYTE *)(tbl+ID_HEAD_OFFSET);  // skip first 4 bytes header
    
    do {
        if(!PCAM_GetCustomerDataTag(&tagID, &tagLength, &tblBuf, len)) {
            if(tagID == tag)
                break;
            len = len - tagLength;
            tblBuf += tagLength;
        }
    }while(len > 0); 
    
    return (MMP_ULONG)(tblBuf - tbl);        
}

const __align(4) MMP_UBYTE Customer_Table_Setting_Default[0x40] = {
0xEE, // tag
0x01, //version 1
0x40, 0x00,
0xEE, // offset 0x0004
0x01,
0x08, 0x00, // Field length, //included tag,id,length
LOBYTE(0x114D),      
HIBYTE(0x114D),      
#if (CUSTOMER == ASU)
    #if (MODEL == 1)
//12P2SF171A//dual sensor
LOBYTE(0x071A),     
HIBYTE(0x071A),     
    #elif (MODEL == 2)
//12P2SF140/12P2SF171
LOBYTE(0x0140),     
HIBYTE(0x0140),     
    #else
LOBYTE(0x8433),     
HIBYTE(0x8433),     
    #endif
#else
LOBYTE(0x8C00),     
HIBYTE(0x8C00),
#endif
0xEE, // offset 0x000c
0x13, // serial number tag
0x34, 0x00, // Field length, //included tag,id,length
0x30,
0x03,
'0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00,
'0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00,
'0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, 
};

void uvc_init_data(MMP_ULONG cd_tbl_addr)
{
    //MMP_UBYTE	ubManufacturerID;
    //MMP_USHORT	usDeviceID;
    //MMP_UBYTE	*ptr;

    RTNA_DBG_Str3("MMPF_PCAM_Init_UVC_Table() start...\r\n");

	//MMPF_SIF_Init();
    if (USB_ResetFlash()) {
#if EN_DBGLOG_FOR_FLASH
        RTNA_DBG_Str(0, "\r\nSIF init error !!\r\n");
#endif
    }

    RTNA_DBG_Str3("  CUSTOMER_INIT_FLASH_ADDR = ");
    RTNA_DBG_Long3(CUSTOMER_INIT_FLASH_ADDR);
    RTNA_DBG_Str3("\r\n");
    RTNA_DBG_Str3("  cd_tbl_addr = ");
    RTNA_DBG_Long3(cd_tbl_addr);
    RTNA_DBG_Str3("\r\n");

	MMPF_SF_ReadData(CUSTOMER_INIT_FLASH_ADDR, cd_tbl_addr, 256);  // read 16KB IQ table into DRAM buffer
    RTNA_DBG_Str3("  customer_table_valid_flag = ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(cd_tbl_addr));
    RTNA_DBG_Str3("\r\n");
    RTNA_DBG_Str3("  cd_tbl_addr = ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(cd_tbl_addr));
    RTNA_DBG_Str3(" : ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(cd_tbl_addr+1));
    RTNA_DBG_Str3(" : ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(cd_tbl_addr+2));
    RTNA_DBG_Str3(" : ");
    RTNA_DBG_Byte3(*(MMP_UBYTE *)(cd_tbl_addr+3));
    RTNA_DBG_Str3("\r\n");
    
    if((*(MMP_UBYTE *)(cd_tbl_addr + CUSTOMER_INIT_DATA_HEAD_OFFSET) == CUSTOMER_INIT_DATA_TAG) &&
        (*(MMP_UBYTE *)(cd_tbl_addr + CUSTOMER_INIT_DATA_HEAD_OFFSET + 1) == 1) ){  // valid customer table, table version should be 1
        RTNA_DBG_Str3(" *** customer table in Flash is valid ***\r\n");
	    MMPF_SF_ReadData(CUSTOMER_INIT_FLASH_ADDR, cd_tbl_addr, CUSTOMER_INIT_FLASH_SIZE);  // read 16KB IQ table into DRAM buffer
	    
    }
    else{
        RTNA_DBG_Str3(" ### customer table in Flash is invalid ###\r\n");
        // load default customer table
        MEMCPY((MMP_UBYTE *)cd_tbl_addr, (MMP_UBYTE *)&Customer_Table_Setting_Default[0], CUSTOMER_INIT_FLASH_SIZE);
        // Write default customer table into flash
        MMPF_SIF_WriteDataEx(CUSTOMER_INIT_FLASH_ADDR, (MMP_ULONG)&Customer_Table_Setting_Default[0], CUSTOMER_INIT_FLASH_SIZE);
    }

    gsVIDPID_HEAD_OFFSET = PCAM_Search_CustomerData_Offset((MMP_UBYTE *)cd_tbl_addr, CUSTOMER_INIT_FLASH_SIZE, VIDPID_TAG);
    dbg_printf(3, "gsVIDPID_HEAD_OFFSET = 0x%x\r\n", gsVIDPID_HEAD_OFFSET);
    gsSNSTRING_HEAD_OFFSET = PCAM_Search_CustomerData_Offset((MMP_UBYTE *)cd_tbl_addr, CUSTOMER_INIT_FLASH_SIZE, SNSTRING_TAG);
    dbg_printf(3, "gsSNSTRING_HEAD_OFFSET = 0x%x\r\n", gsSNSTRING_HEAD_OFFSET);

    RTNA_DBG_Str3("MMPF_PCAM_Init_UVC_Table() end...\r\n");

}
#endif

#if (CUSTOMER == PNS)
void PNS_SOLENOID_CTRL(void)
{
    AITPS_GPIO  pGPIO = AITC_BASE_GPIO;
	extern MMP_UBYTE POP_UP_LOOP;

	if((((pGPIO->GPIO_DATA[0]&0x40000)>>SW_SIG)==0)||(POP_UP_LOOP==1)){
		GPIO_OutputControl(S_DRIVE, MMP_TRUE);
		MMPF_OS_Sleep_MS(100);
		GPIO_OutputControl(S_DRIVE, MMP_FALSE);
		dbg_printf(0,"TV Camera pop up!!!\r\n");
	}
}
MMP_BOOL Disable_Capture=0;
void cbSolenoid_Switch_ISR(MMP_ULONG pin)	//Whether the detection of Solenoid changes to low
{
    AITPS_GPIO  pGPIO = AITC_BASE_GPIO;
    if(((pGPIO->GPIO_DATA[0]&0x40000)>>SW_SIG)==0) {
        usb_vc_capture_trigger(1);
        dbg_printf(3,"Solenoid State Down!!!\r\n");
        Disable_Capture = 1;
    } else {
        usb_vc_capture_trigger(0);
        dbg_printf(3,"Solenoid State Clear!!!\r\n");
    }
}
#endif

#if (IQ_SETTING_LOAD_FROM_FLASH)
MMP_UBYTE IQ_Setting[IQ_SETTING_MAX_SIZE];
#endif
#if (UVC_SETTING_LOAD_FROM_FLASH)
MMP_UBYTE Customer_Table_Setting[CUSTOMER_INIT_FLASH_SIZE];
#endif

extern  MMP_UBYTE gbUsbHighSpeed;

#if (SUPPORT_OSD_FUNC)
MMP_USHORT gsOSD_WIDTH_MAX_WORD;
#endif

MMP_USHORT pCamTaskInited = 0 ;
#include "mmpf_pio.h"
#if SUPPORT_PWM
#include "mmpf_pwm.h"
#endif

#ifdef ZDW_BARCODE
//Ken Chang
#include "mmp_reg_ibc.h"
#include "kk_memAdm.h"
MMP_BOOL bFirstFrame = FALSE;
//MMP_UBYTE* bufVGA;
//MMP_UBYTE* bufDecode;
#ifndef ZDW_BARCODE_BTN_USER_MODE
extern MMP_BOOL bScaning;
#endif
extern MMP_BOOL bScanned;
extern MMP_ULONG m_systick2;
extern MMP_ULONG m_scntick;
//extern MMP_BOOL bAcruiring;
extern int iScnCount;
extern MMP_ULONG bounceCnt;
extern MMP_BOOL bBtnPressed;
MMP_ULONG btnclk = 0;
MMP_BOOL bReady = FALSE;
//extern MMP_BOOL bPowerOnWorking;
MMP_UBYTE uTrueLevel=1;
extern int iScanCnt;
#endif

#define USE_RESET_SLOT_FUNC 1
#if STREAM_CFG_VER >= 2 && USE_RESET_SLOT_FUNC
void PCAM_USB_ResetSlotBuf(MMP_USHORT pipe, MMP_USHORT num, MMP_ULONG addr, MMP_ULONG size)
{
    PIPE_INFO(pipe,b).total_rd = PIPE_INFO(pipe,b).total_wr = 0;
    PIPE_INFO(pipe,b).rd_index = PIPE_INFO(pipe,b).wr_index = 0;
    PIPE_INFO(pipe,b).buf_addr = addr;
    PIPE_INFO(pipe,b).slot_size = size;
    PIPE_INFO(pipe,b).slot_num = num;
}
#endif


#ifdef ZDW_BARCODE

void Turn_On_Off_W_LED(MMP_BOOL bOnOff)
{
	GPIO_OutputControl(MMPF_PIO_REG_GPIO43, bOnOff);
}

void Turn_On_Off_R_LED(MMP_BOOL bOnOff)
{
	GPIO_OutputControl(MMPF_PIO_REG_GPIO42, bOnOff);
}

void Turn_On_Off_READY_LED(MMP_BOOL bOnOff)
{
	GPIO_OutputControl(MMPF_PIO_REG_GPIO41, bOnOff);
}

//Added by Ken for GPIO call back
void CallBack_ISR(MMP_ULONG pin)
{
	if(pin == MMPF_PIO_REG_GPIO40) //Trigger by user
	{
		MMP_UBYTE uLevel;
		AITPS_GPIO  pGPIO = AITC_BASE_GPIO;
			
		uLevel = (pGPIO->GPIO_DATA[1]&0x100)>>8;

		//if((uPreLevel!=uLevel)&&(uLevel == 0))
		uTrueLevel = uLevel;

		btnclk = m_systick2;
	}

}
#endif

void MMPF_PCAM_Task(void)
{
//#if (CUSTOMER == NMG) || ((CUSTOMER == PNS)&&(MODEL == 1)) || (CUSTOMER == ANW)
    AITPS_GBL   pGBL = AITC_BASE_GBL;
//#endif
    //AITPS_GPIO  pGPIO = AITC_BASE_GPIO;
    //AITPS_PAD   pPAD = AITC_BASE_PAD;
    //AITPS_AIC   pAIC = AITC_BASE_AIC;
    MMP_USHORT err = PCAM_ERROR_NONE ;
    pcam_msg_t *msg ;
#if SUPPORT_UAC && ((AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778) || (AUDEXT_DAC==ADC3101) || (AUDEXT_DAC==WM8960))
    PCAM_AUDIO_CFG *pcam_audio = pcam_get_audio_cfg();
#endif

    //RTNA_DBG_Str3("MMPF_PCAM_Task,Payload Header Size:");
    //RTNA_DBG_Byte3(FRAME_PAYLOAD_HEADER_SZ);
    //RTNA_DBG_Str3("\r\n");

#if (IQ_SETTING_LOAD_FROM_FLASH)
    MMPF_PCAM_Init_IQ_Setting((MMP_ULONG)(&IQ_Setting[0]));
#endif

#if (UVC_SETTING_LOAD_FROM_FLASH)
    uvc_init_data((MMP_ULONG)(&Customer_Table_Setting[0]));
#endif

    MMPF_PIO_Initialize();

#if (CUSTOMER == NMG)

    #if 0//(CHIP == P_V2)
    pGBL->GBL_CHIP_CFG_EN = 1;
    RTNA_WAIT_MS(5);
    pGBL->GBL_CHIP_CFG &= ~(0x2000); // Depends on SIF PAD.
    RTNA_WAIT_MS(5);
    #endif
  
    #if (SNAP_PIN!=255)
    pPAD->PAD_GPIO[SNAP_PIN] = PAD_E4_CURRENT;
	MMPF_PIO_EnableOutputMode(SNAP_PIN, MMP_FALSE);
	MMPF_PIO_EnableTrigMode(SNAP_PIN, MMPF_PIO_TRIGMODE_EDGE_H2L, MMP_TRUE);
	MMPF_PIO_EnableInterrupt(SNAP_PIN, MMP_TRUE, 0x0, NULL);
    #endif
    #if (FLIP_PIN!=255)
    pPAD->PAD_GPIO[FLIP_PIN] = PAD_E4_CURRENT;
	MMPF_PIO_EnableOutputMode(FLIP_PIN, MMP_FALSE);
	MMPF_PIO_EnableTrigMode(FLIP_PIN, MMPF_PIO_TRIGMODE_EDGE_H2L, MMP_TRUE);
	MMPF_PIO_EnableInterrupt(FLIP_PIN, MMP_TRUE, 0x0, NULL);
    #endif
    #if (IRHID_PIN!=255)
    pPAD->PAD_GPIO[IRHID_PIN] = PAD_E4_CURRENT;
	MMPF_PIO_EnableOutputMode(IRHID_PIN, MMP_FALSE);
	MMPF_PIO_EnableTrigMode(IRHID_PIN, MMPF_PIO_TRIGMODE_EDGE_L2H, MMP_TRUE);
	MMPF_PIO_EnableInterrupt(IRHID_PIN, MMP_TRUE, 0x0, NULL);
    #endif
    //RTNA_DBG_Str3("PIO Initialize\r\n");
#endif

    #if (SUPPORT_OSD_FUNC)
    #if (CUSTOMER == ANW)
    gsOSD_WIDTH_MAX_WORD = 21;  // 24 Hour need 21 words, 12 Hour need 24 words
    pcam_SetClock(2015, 2, 17, 12, 00, 00);//temporary init time before XU cmd
    #else
    gsOSD_WIDTH_MAX_WORD = 20;
    pcam_SetClock(2015, (TRUNK_BCD>>12)*10+((TRUNK_BCD>>8)&0xF), ((TRUNK_BCD>>4)&0xF)*10+(TRUNK_BCD&0xF), 11, 59, 30);//temporary init time before XU cmd
    #endif
    // Initial OSD default color
    pcam_Osd_TranslateRGB2YUV(OSD_FOREGROUND_COLOR_R, OSD_FOREGROUND_COLOR_G, OSD_FOREGROUND_COLOR_B, &gbOSDForeColorY, &gsOSDForeColorUV);
    pcam_Osd_TranslateRGB2YUV(OSD_BACKGROUND_COLOR_R, OSD_BACKGROUND_COLOR_G, OSD_BACKGROUND_COLOR_B, &gbOSDBackColorY, &gsOSDBackColorUV);
    
    #if (MAINTAIN_RTC_TIME_METHOD==USE_SW_TIMER_TRIGGER)
    pcam_UpdateTime_StartTimer();
    #endif
    #endif

#if (CUSTOMER == PNS) && (MODEL == 1)
	MMPF_PIO_EnableOutputMode(SW_SIG, MMP_FALSE);
	MMPF_PIO_EnableGpioMode(SW_SIG, MMP_TRUE);
	pGBL->GBL_IO_CFG_PBGPIO[SW_SIG-0x08] &= 0xFD;   //Disable Input pull-down
	pGBL->GBL_IO_CFG_PBGPIO[SW_SIG-0x08] |= 0x04;   //Enable Input pull-high
	MMPF_PIO_EnableTrigMode(SW_SIG, MMPF_PIO_TRIGMODE_EDGE_H2L, MMP_TRUE);
	MMPF_PIO_EnableTrigMode(SW_SIG, MMPF_PIO_TRIGMODE_EDGE_L2H, MMP_TRUE);
	MMPF_PIO_EnableInterrupt(SW_SIG, MMP_TRUE, 0x0, cbSolenoid_Switch_ISR);
#endif
#if (CUSTOMER == ANW)
	MMPF_PIO_EnableOutputMode(IR_LED, MMP_TRUE);
	MMPF_PIO_EnableGpioMode(IR_LED, MMP_TRUE);
	pGBL->GBL_IO_CFG_PBGPIO[IR_LED-0x08] &= 0xFB;   //Disable Input pull-high
	pGBL->GBL_IO_CFG_PBGPIO[IR_LED-0x08] |= 0x02;   //Enable Input pull-down
    MMPF_PIO_EnableOutputMode(ICR_SW, MMP_TRUE);
	MMPF_PIO_EnableGpioMode(ICR_SW, MMP_TRUE);
	pGBL->GBL_IO_CFG_PBGPIO[ICR_SW-0x08] &= 0xFB;   //Disable Input pull-high
	pGBL->GBL_IO_CFG_PBGPIO[ICR_SW-0x08] |= 0x02;   //Enable Input pull-down
	/*#if 1   //0:Night mode[IR_LED(1),ICR_SW(0)] 1:Day mode[IR_LED(0),ICR_SW(1)]
	GPIO_OutputControl(IR_LED, MMP_FALSE);
	MMPF_OS_Sleep_MS(500);
	GPIO_OutputControl(ICR_SW, MMP_TRUE);
	MMPF_OS_Sleep_MS(1500);
	GPIO_OutputControl(ICR_SW, MMP_FALSE);
	#else
	GPIO_OutputControl(IR_LED, MMP_TRUE);
	MMPF_OS_Sleep_MS(1000);
	GPIO_OutputControl(ICR_SW, MMP_TRUE);
	MMPF_OS_Sleep_MS(1500);
	GPIO_OutputControl(ICR_SW, MMP_FALSE);
	#endif*/
	MMPF_PIO_EnableOutputMode(VER_0, MMP_FALSE);
	MMPF_PIO_EnableGpioMode(VER_0, MMP_TRUE);
	MMPF_PIO_EnableOutputMode(VER_1, MMP_FALSE);
	MMPF_PIO_EnableGpioMode(VER_1, MMP_TRUE);
#endif

//    #if (MicSource == MicInPathI2S)
//    MMPF_Init_ExteralDac();
//    #endif
    // sean@2010_09_14 , move to after MMPF_PCAM_StartUSB()
    // Because MMPF_Init_DefaultClock() turn off SPI clock which USB used for Phy cfg.
    // MMPF_Init_DefaultClock();

// Start enum at last task (lowest prio)    
#if USB_ENUM_AT_TASK_SUSPEND==1
    MMPF_PCAM_StartUSB();
#endif    

    //MMPF_Init_DefaultClock();
    MMPF_Init_DefGain();
    if(gbUsbHighSpeed == 1){
        usb_set_mjpg_quality(PCCAM_DEFAULT_QF);  // set MJPEG q scaling factor
    }
    else{
        usb_set_mjpg_quality(0x40);  // set MJPEG q scaling factor
    }

#if 0
    MMPF_DumpReg(0x80006E00, 256);
    MMPF_DumpReg(0x80006900, 256);
#endif

    RTNA_DBG_Str3("MMPF_PCAM_Task End...\r\n");

    pCamTaskInited = 1;
    
    
#ifdef ZDW_BARCODE
#ifdef ZDW_BARCODE_POWER_ON_WORKING
//	if(bPowerOnWorking){
	//To encode YUV right after power on
		usb_vc_get_video_probe(1,1,1);    //Set YUY2 VGA format
		usb_uvc_start_preview();       //Start Encoder
		
//	}

#endif
#endif
    
    while(TRUE) {
        msg = MMPF_PCAM_GetMsg();
        if(!msg) {
            continue ;
        }
#if 0
        RTNA_DBG_Str(3,"msg->msg_id:");
        RTNA_DBG_Short(3,msg->msg_id);
        RTNA_DBG_Str(3,"\r\n");
#endif        
        switch(msg->msg_id) {
#if SUPPORT_UAC
	    case PCAM_MSG_USB_AUDIO_RESET:
		    if(glAudioEnable){
        	    RTNA_DBG_Str(3,"Trying to reset external audio codec\r\n");
        	    MMPF_Audio_TimerClose(MMPF_TIMER_2);

#if ((CUSTOMER == CCN)&&(MODEL == 1)) || (CUSTOMER == LIT) || ((CUSTOMER == LGT)&&(MODEL == 1)) || ((CUSTOMER == ANW)&&(AUDEXT_DAC == CX20709))
    			GPIO_OutputControl(CNX_RST, FALSE); // for CXNT RESET. CGPIO2
	    		RTNA_WAIT_MS(10);
		    	GPIO_OutputControl(CNX_RST, TRUE);
#endif			
  		        MMPF_OS_Sleep_MS(2000); // wait 2 sec for CXNT ready.
			    glAudioCodecInit = FALSE;

		#if (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778)
			    MMPF_InitCX20709(pcam_audio->pCamSampleRate);
		#endif
		
		#if (AUDEXT_DAC==ADC3101)
			    MMPF_InitTLV320ADC3101(pcam_audio->pCamSampleRate);
			    MMPF_PowerUpTLV320ADC3101(pcam_audio->pCamSampleRate);
		#endif

        #if (AUDEXT_DAC==WM8750) || (AUDEXT_DAC==WM8960)
                InitExtLineIn();
                PowerUpExtLinIn(pcam_audio->pCamSampleRate);
        #endif

        	    MMPF_Audio_TimerOpen(UAC_TIMER_MS_LENGTH, MMPF_TIMER_2);
            }
			break;
#endif			
        case PCAM_MSG_USB_INIT:
            err = PCAM_USB_Init(msg);
            break;
        case PCAM_MSG_USB_PREVIEW_START:
            err = PCAM_USB_PreviewStart(msg);
            break;
        case PCAM_MSG_USB_PREVIEW_STOP:
            err = PCAM_USB_PreviewStop(msg);
            break;
        case PCAM_MSG_USB_EXIT:
            err = PCAM_USB_Exit(msg);
            break;
        case PCAM_MSG_USB_UPDATE_OSD:
            err = PCAM_USB_UpdateOSD(msg);
            break;
        case PCAM_MSG_USB_SET_ATTRS:
            err = PCAM_USB_SetAttrs(msg);
            break;    
        case PCAM_MSG_USB_CAPTURE:
            err = PCAM_USB_TakePicture(msg);
            break ;  
#if SUPPORT_UAC
        case PCAM_MSG_USB_AUDIO_START:
            err = PCAM_USB_AudioStart(msg);
            break;
        case PCAM_MSG_USB_AUDIO_STOP:
            err = PCAM_USB_AudioStop(msg);
            break;
        case PCAM_MSG_USB_AUDIO_VOL:
            err = PCAM_USB_SetVolume(msg);
            break;
        case PCAM_MSG_USB_AUDIO_MUTE:
            err = PCAM_USB_SetMute(msg);
            break;
        case PCAM_MSG_USB_AUDIO_SET_SAMPLINGRATE:
			err = PCAM_USB_SetSamplingRate(msg);
            break;
		case PCAM_MSG_USB_AUDIO_SETMODE:
			#if AUDEXT_DAC==CX20709
			PCAM_USB_AudioSetMode(msg);
			#endif
			break;          
#endif            
        case PCAM_MSG_USB_UPDATE_FW:
            err = PCAM_USB_UpdateFirmware(msg) ;
            break; 
        case PCAM_MSG_USB_CHECK_ALIVE:
            err = PCAM_USB_TaskAlive(msg);
            break ; 
        case PCAM_MSG_USB_CAPTURE_RAW:
            err = PCAM_USB_TakeRawPicture(msg);
            break ;                 
        }
        msg->err = err;
        /*Handler processed done*/
        /*Release semaphore*/
        if(msg->msg_sem) {
            MMPF_OS_ReleaseSem(*msg->msg_sem);
        } else {
            pcam_free_msg(msg);
        }
    }
}


pcam_msg_t *MMPF_PCAM_GetMsg(void)
{
    MMPF_OS_FLAGS flags;
    pcam_msg_t *msg;
    /*
    Get message first in case there has multiple messages
    */

    msg = (pcam_msg_t *)pcam_get_msg();
    if(msg) {
        return msg ;
    }

    /*
    Wait message event
    */
    MMPF_OS_WaitFlags(PCAM_Flag, (PCAM_FLAG_MSG | PCAM_FLAG_OVERWR_MSG),
                     (MMPF_OS_FLAG_WAIT_SET_ANY | MMPF_OS_FLAG_CONSUME),
                     0, &flags);
    if(flags & PCAM_FLAG_OVERWR_MSG) {
        msg = (pcam_msg_t *)pcam_get_overwr_msg();
        if(msg) {
            return msg ;
        }
    }                     
    if(flags & PCAM_FLAG_MSG) {
        msg = (pcam_msg_t *)pcam_get_msg();
        if(msg) {
            return msg ;
        }
    }
    return (pcam_msg_t *)0;
}

MMP_USHORT PCAM_USB_Init(pcam_msg_t *msg)
{
    return PCAM_ERROR_NONE ;
}

//move to mmpf_pio.c
#if 0
void GPIO_OutputControl(MMP_UBYTE num, MMP_UBYTE status)
{
    AITPS_GPIO  pGPIO = AITC_BASE_GPIO;
    #if (CHIP == P_V2)
    AITPS_PAD   pPAD = AITC_BASE_PAD;
    #endif
    AITPS_GBL   pGBL = AITC_BASE_GBL;

    if(num < 32){
        #if (CHIP == P_V2)
        pPAD->PAD_GPIO[num] = (PAD_E8_CURRENT | PAD_PULL_LOW) ;
        #endif

        if(num < 8){
            pGBL->GBL_IO_CTL5 |= (1 << num);
        }
        else if(num < 16){
            pGBL->GBL_IO_CTL6 |= (1 << (num - 8));
        }
        else if(num < 24){
            pGBL->GBL_IO_CTL7 |= (1 << (num - 16));
        }
        else{
            pGBL->GBL_IO_CTL8 |= (1 << (num - 24));
        }

        pGPIO->GPIO_EN[0] |= (1 << num); // config as output mode
        if(status == TRUE)
            pGPIO->GPIO_DATA[0] |= (1 << num);  
        else
            pGPIO->GPIO_DATA[0] &= ~(1 << num);  
    }
    else if(num < 64){
        #if (CHIP == P_V2)
        pPAD->PAD_GPIO[num] = (PAD_E8_CURRENT | PAD_PULL_LOW) ;
        #endif

        if(num < 40){
            //pGBL->GBL_IO_CTL9 |= (1 << (num - 32));
        }
        else if(num < 48){
            pGBL->GBL_IO_CTL10 |= (1 << (num - 40));
        }

        pGPIO->GPIO_EN[1] |= (1 << (num-32)); // config as output mode
        if(status == TRUE)
            pGPIO->GPIO_DATA[1] |= (1 << (num-32));  
        else
            pGPIO->GPIO_DATA[1] &= ~(1 << (num-32));  
    }

}

#if (CHIP == P_V2)
void GPIO_InputPinControl(MMP_UBYTE num, MMP_UBYTE pad_status, MMP_UBYTE int_dir)
{
    AITPS_GPIO  pGPIO = AITC_BASE_GPIO;
    AITPS_PAD   pPAD = AITC_BASE_PAD;

    if(num < 32){
        pPAD->PAD_GPIO[num] = pad_status;
        pGPIO->GPIO_EN[0] &= ~(1 << num); // config as input mode
        if(int_dir == GPIO_INT_H2L){
            pGPIO->GPIO_INT_L2H_EN[0] &= ~(1 << num);
            pGPIO->GPIO_INT_H2L_EN[0] |= (1 << num);
        }
        else{
            pGPIO->GPIO_INT_L2H_EN[0] |= (1 << num);
            pGPIO->GPIO_INT_H2L_EN[0] &= ~(1 << num);
        }
        pGPIO->GPIO_INT_CPU_SR[0] = (1 << num);
        pGPIO->GPIO_INT_CPU_EN[0] |= (1 << num);
    }
    else if(num < 64){
        pPAD->PAD_GPIO[num] = pad_status;
        pGPIO->GPIO_EN[1] &= ~(1 << (num-32)); // config as input mode
        if(int_dir == GPIO_INT_H2L){
            pGPIO->GPIO_INT_L2H_EN[1] &= ~(1 << (num-32));
            pGPIO->GPIO_INT_H2L_EN[1] |= (1 << (num-32));
        }
        else{
            pGPIO->GPIO_INT_L2H_EN[1] |= (1 << (num-32));
            pGPIO->GPIO_INT_H2L_EN[1] &= ~(1 << (num-32));
        }
        pGPIO->GPIO_INT_CPU_SR[1] = (1 << (num-32));
        pGPIO->GPIO_INT_CPU_EN[1] |= (1 << (num-32));
    }

}
#endif
#endif

//#include "mmp_reg_rawproc.h"
/*
void PCAM_USB_SetH264StartMode(void)
{
    MMPF_VIDENC_GOP_CTL     GopCtl;
    MMPF_VIDENC_MAX_FPS_CTL FpsCtl;
    MMPF_VIDENC_SLICE_CTL   SliceCtl;
// New in 8423
    if((ISP_IF_AE_GetFPS() == 0) || (ISP_IF_AE_GetFPS() > 30)){  // Auto
        gsVideoEncodeFPS = 30;
    }
    else{
        gsVideoEncodeFPS = ISP_IF_AE_GetFPS();
    }
    FpsCtl.ulMaxFpsResolution = gsVideoEncodeFPS*VIDEO_FPS_SCALE;
    FpsCtl.ulMaxFpsIncreament = VIDEO_FPS_SCALE;
    MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_MAX_FPS, (void*)&FpsCtl);
    
    #if 0//FPS_CTL==1
    if(gbVideoEncQualityCustom == MMP_TRUE){
        glCustomTargetSizePerFrame = (MMPF_VIDENC_GetBitrate(0))/(8 * gsVideoEncodeFPS);
        gbCustomQp = 45;
    } 
    #endif       
#if 0        
    if(pCamCtx.videoQuality  == VIDRECD_QUALITY_HIGH) {
        GopCtl.usGopSize = 31;
    }    
    else {
        GopCtl.usGopSize = 127;
    }    
#else
    GopCtl.usGopSize = 3000;
#endif   
    GopCtl.usMaxContBFrameNum = 0;
    MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_GOP_CTL, (void*)&GopCtl);

    // Set default profile 
    #if H264_PROFILE == H264_BASELINE_PROFILE
    MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_PROFILE, (void*)BASELINE_PROFILE); //julian dbg for iq, sec
    #endif
	#if H264_PROFILE == H264_HIGH_PROFILE
    MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_PROFILE, (void*)FREXT_HP);//Gason@20111227,for Quality QA
    #endif

    MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_LEVEL, (void*)40);

    // Set default slice per frame
    SliceCtl.SliceMode = MMPF_VIDENC_SLICE_MODE_FRM;
    SliceCtl.ulSliceSize = 0;
    MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_SLICE_CTL, (void*)&SliceCtl);
}
*/
/*
#define USE_RESET_SLOT_FUNC 1
#if STREAM_CFG_VER >= 2 && USE_RESET_SLOT_FUNC
void PCAM_USB_ResetSlotBuf(MMP_USHORT pipe, MMP_USHORT num, MMP_ULONG addr, MMP_ULONG size)
{
    PIPE_INFO(pipe,b).total_rd = PIPE_INFO(pipe,b).total_wr = 0;
    PIPE_INFO(pipe,b).rd_index = PIPE_INFO(pipe,b).wr_index = 0;
    PIPE_INFO(pipe,b).buf_addr = addr;
    PIPE_INFO(pipe,b).slot_size = size;
    PIPE_INFO(pipe,b).slot_num = num;
}
#endif
*/
extern MMP_ULONG glEndOfH264SramAddr;
#if RAW_DATA_EN
MMP_USHORT gsFrameDataWithRaw = 0;
MMP_ULONG glRawStartAddr = 0;
MMP_ULONG glRawBuffer = 0;
#endif
extern MMP_ULONG _usbDescList ;
//extern MMP_ULONG _usbDescList1;
extern USB_DMA_DESC *pUsbDmaDesc;
MMP_USHORT PCAM_USB_PreviewStart(pcam_msg_t *msg)
{
    static MMP_BOOL bFirstInit = MMP_TRUE;
extern MMP_ULONG glPCCAM_VIDEO_BUF_ADDR;
extern MMP_ULONG glPCCAM_VIDEO_BUF_MAX_SIZE;
extern MMP_ULONG glUSB_UVC_DMA_BUF_ADDR1 ;
extern MMP_ULONG glUSB_UVC_DMA_BUF_ADDR2 ;
extern MMP_UBYTE gbCurH264Type ;
extern MMP_ULONG glPccamResolution ;
extern MMP_UBYTE gbStillCaptureEvent;

#if DRAM_SIZE > 2
#if UVC_DMA_3K_NUM > 0
    extern MMP_USHORT UVCTxFIFOSize;
#endif
#if (IQ_TABLE_LOAD_FROM_FLASH)
extern	MMP_ULONG	m_glISPBufferStartAddr;
#endif
#endif

// Non-Cachable FB address for pCam

   // MMP_USHORT      err = PCAM_ERROR_NONE ;
    MMP_ULONG       cur_buf;
    MMP_ULONG ulSize;
    //MMP_ULONG       pccam_compbuf_size;
    PCAM_USB_INFO   *pcam_info = (PCAM_USB_INFO *)msg->msg_data ;
    const STREAM_CFG      *stream_cfg ;
    STREAM_CTL      cur_bctl ;
    MMP_USHORT      aligned_header_size ,aligned_off = 0;
	MMP_SHORT      init_count = 3;
	MMP_ERR        err;
    
    MMPD_System_EnableClocks(PCAM_PREVIEW_CLOCKS, MMP_TRUE);
    /*
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_JPG, MMP_TRUE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_SCAL, MMP_TRUE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_RAWPROC, MMP_TRUE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_H264, MMP_TRUE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_DMA, MMP_TRUE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_ICON, MMP_TRUE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_IBC, MMP_TRUE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_GRA, MMP_TRUE);
    */

    RTNA_DBG_Str3("PCAM_USB_PreviewStart\r\n");
#if ALIGN_PAYLOAD==1
    
    if(FRAME_PAYLOAD_HEADER_SZ > 32) {
        aligned_header_size = 64 ;
    
    } else {
        aligned_header_size = 32 ;
    }
    aligned_off = aligned_header_size - FRAME_PAYLOAD_HEADER_SZ ;
#else
    aligned_header_size = FRAME_PAYLOAD_HEADER_SZ ; 
#endif
    
    pCamCtx.videoQuality = PCAM2MMP_Get_Quality(pcam_info);
    pCamCtx.videoRes = PCAM2MMP_Get_Resolution(pcam_info);
    pCamCtx.videoFormat = PCAM2MMP_Get_VideoFormat(pcam_info);
#if SUPPORT_UAC
    pCamCtx.audioFormat = PCAM2MMP_Get_AudioFormat(pcam_info);
#endif
    pCamCtx.debandMode = PCAM2MMP_Get_DebandMode(pcam_info);
    m_VideoFmt = pCamCtx.videoFormat ;
    m_usVideoQuality = pCamCtx.videoQuality ;
    
        //RTNA_DBG_Str(0, "  ** videoRes = ");       
        //RTNA_DBG_Short(0, pCamCtx.videoRes);
        //RTNA_DBG_Str(0, "\r\n");
        //RTNA_DBG_Str(0, "  ** videoFormat = ");       
        //RTNA_DBG_Short(0, pCamCtx.videoFormat);
        //RTNA_DBG_Str(0, "\r\n");
        //RTNA_DBG_Str(0, "  ** glPccamResolution = ");       
        //RTNA_DBG_Short(0, glPccamResolution);
        //RTNA_DBG_Str(0, "\r\n");
    // to fix Skype FOV consistency issue @ 2011_05_06
    if (m_VideoFmt == MMPS_3GPRECD_VIDEO_FORMAT_H264){
        extern MMP_USHORT  m_usZoomResolution;
        if(m_usResolType == VIDRECD_RESOL_160x120){
            #if BIND_SENSOR_OV2710 || BIND_SENSOR_S5K5B3GX
            m_usZoomResolution = 68;//60;  // for 1080p sensor
            #else
            m_usZoomResolution = 90;//60;  // for 720p sensor
            #endif            
        }
        else{
            #if BIND_SENSOR_AR0330
            m_usZoomResolution = 72;//2304x1296 greatest common factor is 144 but >128 So take half of the 72
            #else
            m_usZoomResolution = 80;//1280x720 greatest common factor is 80
            #endif
        }
    }

    MMPS_3GPRECD_InitVideoInfo(); //init all stream default param

    glEndOfH264SramAddr = 0x100000;
    MMPF_SYS_InitFB();

    // Allocate FrameBuffer for 3A
    ulSize = MMPF_Sensor_CalculateBufferSize();

    #if (IQ_TABLE_LOAD_FROM_FLASH == 0)
    cur_buf = (MMP_ULONG)MMPF_SYS_AllocFB("ISP",ulSize,32);
    #else
    #if DRAM_SIZE > 2
    cur_buf = (MMP_ULONG)MMPF_SYS_AllocFB("ISP(CIQ)",ulSize+IQ_TABLE_MAX_SIZE,32);
    #else
    cur_buf = (MMP_ULONG)MMPF_SYS_AllocFB("ISP",ulSize,32);
    #endif
    #endif

#if DRAM_SIZE > 2
    MMPF_Sensor_AllocateBuffer(cur_buf);
#endif

#if (IQ_TABLE_LOAD_FROM_FLASH)
#if DRAM_SIZE > 2
    MMPF_PCAM_Init_IQ_Table(m_glISPBufferStartAddr + ISP_BUFFER_SIZE, gbCurrentSensor);
#else
    MMPF_PCAM_Init_IQ_Table(FW_DOWNLOAD_BUFFER, gbCurrentSensor);
#endif
#endif

    stream_cfg = usb_get_stream_cfg();

    //if(gbStillCaptureEvent == 0){  // if event is not still capture
    //     1. Initialize sensor.
    //    MMPS_Sensor_Initialize(gbCurrentSensor, 1, SENSOR_VIDEO_PRW_MODE);
    //}
    
#if XU_FRAMEBASE_CAPTURE
if(!gFramebaseCap.JPEG && gbStillCaptureEvent!=STILL_IMAGE_SENDING)
#endif
{
init_sensor:

#if (BIND_SENSOR_MT9D111)
    if( mt9d111_inited == 0)
    {
#endif
    //MMPS_Sensor_Initialize(gbCurrentSensor, 1, SENSOR_VIDEO_PRW_MODE);
    MMPD_Sensor_Initialize(gbCurrentSensor, 0, 1, 0);
#if 0
	MMPF_VIF_EnableInputInterface(MMP_TRUE);
	err = MMPF_Sensor_CheckFrameStart(1);
	MMPF_VIF_EnableInputInterface(MMP_FALSE);
	if (err != MMP_ERR_NONE) {  
		MMPF_Sensor_PowerDown(gbCurrentSensor);
		init_count-- ;
		if(init_count > 0) {
		    goto init_sensor;
		}
	}
	if(init_count==0) {
	    dbg_printf(0,"#Sensor init failed:%x,%d\r\n",err,init_count);
    }
#endif
#if (BIND_SENSOR_MT9D111)
    mt9d111_inited = 1;
    }
#endif
}
#if (CUSTOMER == PNS)
	#if (SECS_VER > 20)//if H264 or SECS case, min fps =15
	if((gbCurH264Type==SKYPE_TX_STREAM)||(m_VideoFmt==MMPS_3GPRECD_VIDEO_FORMAT_H264))
	{
	    ISP_IF_AE_SetSysMode(0);
	    ISP_IF_AE_SetMinFPSx10(150);
	}else// other format, min fps = 1
	#endif
	{
	    ISP_IF_AE_SetSysMode(1);
	    ISP_IF_AE_SetMinFPSx10(10);
	}
#endif

    USB_SetPowerLineFreq(PCAM_NONBLOCKING,DEFAULT_FLICKER_MODE);    //Set again Filter after ISP initialization

    // 2. Allocate UVC DMA buffer ( double-buffer )
#if DRAM_SIZE <= 2
{
    /*extern UVC_VIDEO_PAYLOAD_HEADER glUVCPayloadheader[UVC_DMA_3K_NUM];
    glUSB_UVC_DMA_BUF_ADDR1 = (MMP_ULONG)glUVCPayloadheader;
    glUSB_UVC_DMA_BUF_ADDR2 = (MMP_ULONG)(glUVCPayloadheader+1);*/
    _usbDescList = (MMP_ULONG)MMPF_SYS_AllocFB("LIST1", 0x4000 ,32);
    pUsbDmaDesc =(USB_DMA_DESC*) _usbDescList ;

    glUSB_UVC_DMA_BUF_ADDR1 = (MMP_ULONG)MMPF_SYS_AllocFB("UVC1",TX_PER_FRAME * HS_TX_MAX_PK_SIZE,32);
    glUSB_UVC_DMA_BUF_ADDR2 = (MMP_ULONG)MMPF_SYS_AllocFB("UVC2",TX_PER_FRAME * HS_TX_MAX_PK_SIZE,32);
}
#else
    #if UVC_DMA_3K_NUM > 0
    glUSB_UVC_DMA_BUF_ADDR1 = (MMP_ULONG)MMPF_SYS_AllocFB("UVC1",UVC_DMA_3K_NUM * UVCTxFIFOSize,32);
    glUSB_UVC_DMA_BUF_ADDR2 = (MMP_ULONG)MMPF_SYS_AllocFB("UVC2",UVC_DMA_3K_NUM * UVCTxFIFOSize,32);
    #else
    glUSB_UVC_DMA_BUF_ADDR1 = (MMP_ULONG)MMPF_SYS_AllocFB("UVC1",UVC_DMA_SIZE,32);
    glUSB_UVC_DMA_BUF_ADDR2 = (MMP_ULONG)MMPF_SYS_AllocFB("UVC2",UVC_DMA_SIZE,32);
    #endif
#endif
    
#if CAPTURE_RAW_XU
    if (gRawFormat != RAW_CAPTURE_NONE)
    {
        glPCCAM_VIDEO_BUF_MAX_SIZE = GetRawFrameSize(gRawFormat);
    } else
#endif
    if(pCamCtx.videoFormat ==MMPS_3GPRECD_VIDEO_FORMAT_YUV422) {
    #if DRAM_SIZE <= 2
        if (IS_PIPE_RING(stream_cfg,0)) {
            //1K reserved for alignment and headers.
            glPCCAM_VIDEO_BUF_MAX_SIZE = MAX_DRAM_BUF_ADDR - (MMP_ULONG)MMPF_SYS_GetCurFBAddr() - 1*1024;
        } else {
            glPCCAM_VIDEO_BUF_MAX_SIZE = GetYUY2FrameSize(glPccamResolution);
        }
//        glPCCAM_VIDEO_BUF_MAX_SIZE = 320*240*2;//FIXME for ring buffer test
    #else
        glPCCAM_VIDEO_BUF_MAX_SIZE = GetYUY2FrameSize(glPccamResolution);    
    #endif
    }   
    else if(pCamCtx.videoFormat ==MMPS_3GPRECD_VIDEO_FORMAT_YUV420) {
        glPCCAM_VIDEO_BUF_MAX_SIZE = GetYUV420FrameSize(glPccamResolution );
    }
    else if(pCamCtx.videoFormat ==MMPS_3GPRECD_VIDEO_FORMAT_MJPEG) {
#if CAPTURE_BAYER_RAW_ENABLE && (CAPTURE_RAW_XU == 0)
		glPCCAM_VIDEO_BUF_MAX_SIZE = GetRawFrameSize(glPccamResolution);
#else
        glPCCAM_VIDEO_BUF_MAX_SIZE = GetMJPEGFrameSize(glPccamResolution);
#endif
    }
	else if(pCamCtx.videoFormat ==MMPS_3GPRECD_VIDEO_FORMAT_RAW){
		glPCCAM_VIDEO_BUF_MAX_SIZE = GetRawFrameSize(glPccamResolution);
#if RAW_PREVIEW_USING_YUY2_PAYLOAD                    			
		if(glPCCAM_VIDEO_BUF_MAX_SIZE < GetYUY2FrameSize(glPccamResolution))
		    glPCCAM_VIDEO_BUF_MAX_SIZE = GetYUY2FrameSize(glPccamResolution);    
#endif
	}
    else {
    // H264 : Complicate, TBD
    #if SKYPE_MODE_B
        if(gbCurH264Type==SKYPE_H264) {
            glPCCAM_VIDEO_BUF_MAX_SIZE = GetYUY2FrameSize(PCCAM_640_480) / 2  ;    
        }
        else
    #endif
        {
            glPCCAM_VIDEO_BUF_MAX_SIZE = GetH264FrameSize( pCamCtx.videoRes ) ;
        }    
    }
    // Align to 32bytes 
    glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;
    
    glPCCAM_VIDEO_BUF_MAX_SIZE += aligned_header_size;

    UVCX_EnableSliceBasedTx( 0 ); // Also disable in non-h264 format.

    if( pCamCtx.videoFormat ==MMPS_3GPRECD_VIDEO_FORMAT_H264) {
        //glPCCAM_VIDEO_BUF_ADDR += FRAME_PAYLOAD_HEADER_SZ ; // magic
#if SKYPE_MODE_B
        if(gbCurH264Type==SKYPE_H264) {
            //UVCX_EnableSliceBasedTx( 0 );
            // H264 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                #if USE_RESET_SLOT_FUNC
                PCAM_USB_ResetSlotBuf(1, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
                #else
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 12;
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE/2;
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;
                #endif
            }
            else {
            #if DRAM_SIZE == 2
                #if USE_RESET_SLOT_FUNC == 0
                    #error USE_RESET_SLOT_FUNC must be 1 in 8433.
                #endif
                glPCCAM_VIDEO_BUF_MAX_SIZE = 64*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(1, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #else
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                //MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - aligned_header_size));
                #if USE_RESET_SLOT_FUNC
                PCAM_USB_ResetSlotBuf(1, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
                #else
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 3 ; // 3 ring buffer 
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;
                #endif
            #endif
            }
            #if USE_RESET_SLOT_FUNC == 0
            PIPE_INFO(1,b) = cur_bctl ;
            #endif
            if(gbSkypeMode == 0x02) {
            // YUY2 , 1 slot, Frame Src Buffer from CHIP
            #if DRAM_SIZE == 2
                glPCCAM_VIDEO_BUF_MAX_SIZE = 100*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("YUY2",glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(0, 1, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #else
            // YUY2 , 2 slot, Frame Src Buffer from CHIP
                cur_buf = (MMP_ULONG)MMPF_SYS_AllocFB("YUY2",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                #if USE_RESET_SLOT_FUNC
                PCAM_USB_ResetSlotBuf(0, 2, cur_buf, glPCCAM_VIDEO_BUF_MAX_SIZE);
                #else
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 2; // 2 ring buffer 
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
                cur_bctl.buf_addr =  cur_buf ;     
                PIPE_INFO(0,b) = cur_bctl ;
                #endif
            #endif
            }
            }
#else
        if (0) {}
#endif
            
#if USB_MJPEGH264_STREAM//USB_UVC_H264
        else if (gbCurH264Type==UVC_H264){
            H264_ENCODER_VFC_CFG *cur_cfg = usb_get_uvc_h264_cfg();

            if(cur_cfg->bStreamMuxOption & DUAL_MJPEG_H264) {
                // 1/2 size of YUY2
                
                dbg_printf(3, "H.264 %dx%d\r\n", cur_cfg->wWidth, cur_cfg->wHeight);

                
                glPCCAM_VIDEO_BUF_MAX_SIZE =  (cur_cfg->wWidth * cur_cfg->wHeight * 3 )/ 2 ;
                // 1/8 size of YUV420
                glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE / 10 ) + aligned_header_size;
                
                if(glPCCAM_VIDEO_BUF_MAX_SIZE < ( 320*240*3/2 ) )
                    glPCCAM_VIDEO_BUF_MAX_SIZE = 320*240*3/2 ;
                glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;
                    
                if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                    glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",4*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                    MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                    #if USE_RESET_SLOT_FUNC
                    PCAM_USB_ResetSlotBuf(1, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/3);
                    #else
                    cur_bctl.rd_index = cur_bctl.wr_index = 0;
                    cur_bctl.total_rd = cur_bctl.total_wr = 0;
                    cur_bctl.slot_num = 12;
                    cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE/3;
                    cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;
                    #endif
                }
                else {
                    #if USE_RESET_SLOT_FUNC
                    #if DRAM_SIZE == 2
                        PCAM_USB_ResetSlotBuf(1, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
                    #else
                        PCAM_USB_ResetSlotBuf(1, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
                    #endif
                    #else
                    glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                    cur_bctl.rd_index = cur_bctl.wr_index = 0;
                    cur_bctl.total_rd = cur_bctl.total_wr = 0;
                    cur_bctl.slot_num = 3  ; // 3 ring buffer 
                    cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
                    cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;
                    #endif
                }
                #if USE_RESET_SLOT_FUNC == 0
                PIPE_INFO(1,b) = cur_bctl ;
                #endif

                glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("JPEG",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                #if USE_RESET_SLOT_FUNC
                PCAM_USB_ResetSlotBuf(0, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
                #else
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 3  ; // 3 ring buffer 
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;     
                PIPE_INFO(0,b) = cur_bctl ;
                #endif
                // For JPEG 
                MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR,(glPCCAM_VIDEO_BUF_MAX_SIZE-aligned_header_size));
                
            //    glPCCAM_VIDEO_BUF_MAX_SIZE =( glPCCAM_VIDEO_BUF_MAX_SIZE << 1 ) ;
            //    cur_buf = (MMP_ULONG)MMPF_SYS_AllocFB("COMP", glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            //    MMPF_SetPCCAMCompressBuf(cur_buf,glPCCAM_VIDEO_BUF_MAX_SIZE);
            }
        }
#endif            

#if USB_FRAMEBASE_H264_YUY2_STREAM
        else if(gbCurH264Type==FRAMEBASE_H264_YUY2) {

            RES_TYPE_CFG *cur_res = GetResCfg(pCamCtx.videoRes) ;
            //const STREAM_CFG *cur_pipe = usb_get_stream_cfg();

            //UVCX_EnableSliceBasedTx( 0 );

            RTNA_DBG_Str(0, "  ** H264 wWidth = ");
            MMPF_DBG_Int(cur_res->res_w, -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(cur_res->res_h, -4);
            RTNA_DBG_Str(0, "\r\n");

            glPCCAM_VIDEO_BUF_MAX_SIZE =  (cur_res->res_w * cur_res->res_h * 3 )/ 2 ;
            // 1/8 size of YUV420
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE / 10 ) + aligned_header_size;
              
            if(glPCCAM_VIDEO_BUF_MAX_SIZE < ( 320*240*3/2 ) )
                glPCCAM_VIDEO_BUF_MAX_SIZE = 320*240*3/2 ;
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;

            // H264 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 12;
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE/2;
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;     
            }
            else {
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                //MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - aligned_header_size));
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 3 ; // 3 ring buffer 
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;     
            }
            PIPE_INFO(1,b) = cur_bctl ;

            RTNA_DBG_Str(0, "  ** YUY2 wWidth = ");       
            MMPF_DBG_Int(PIPE_INFO(0,w), -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(PIPE_INFO(0,h), -4);
            RTNA_DBG_Str(0, "\r\n");

            glPCCAM_VIDEO_BUF_MAX_SIZE = GetYUY2FrameSize(glPccamResolution) + aligned_header_size;    
            // Align to 32bytes 
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;
    
            // YUY2 , 2 slot, Frame Src Buffer from CHIP
            cur_buf = (MMP_ULONG)MMPF_SYS_AllocFB("YUY2",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            cur_bctl.rd_index = cur_bctl.wr_index = 0;
            cur_bctl.total_rd = cur_bctl.total_wr = 0;
            cur_bctl.slot_num = 2; // 2 ring buffer 
            cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
            cur_bctl.buf_addr =  cur_buf ;     
            PIPE_INFO(0,b) = cur_bctl ;
        }
#endif

#if USB_FRAMEBASE_H264_MJPEG_STREAM
        else if(gbCurH264Type==FRAMEBASE_H264RT_MJPEG) {
        
            #if 0
            RTNA_DBG_Str(0, "  ** H264 wWidth = ");       
            MMPF_DBG_Int(cur_res->res_w, -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(cur_res->res_h, -4);
            RTNA_DBG_Str(0, "\r\n");
            #endif

            // H264 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                PCAM_USB_ResetSlotBuf(1, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
            }
            else {
                glPCCAM_VIDEO_BUF_MAX_SIZE = 50*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(1, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            }

            // MJPEG , 2 slot, Frame Src Buffer from CHIP
            glPCCAM_VIDEO_BUF_MAX_SIZE = 74*1024;
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("MJPEG",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            PCAM_USB_ResetSlotBuf(0, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        }
        else if(gbCurH264Type==FRAMEBASE_H264FRAME_MJPEG) {
            #if SUPPORT_AIT845x_MD || RAW_DATA_EN
            #if (DYNAMIC_CONFIG_CACHEBUF == 1)
            extern void MMPF_MMU_ConfigWorkingBuffer(unsigned int startAddr, unsigned int endAddr, char cacheable);
            #endif
            extern MMP_USHORT MD_x_res, MD_y_res;
            #endif
            // H264 1 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                PCAM_USB_ResetSlotBuf(0, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
            }
            else {
                glPCCAM_VIDEO_BUF_MAX_SIZE = 160*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264 0",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(0, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            }
            RTNA_DBG_Str(0, "  ** 1nd H264 wWidth = ");       
            MMPF_DBG_Int(PIPE_INFO(0,w), -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(PIPE_INFO(0,h), -4);
            RTNA_DBG_Str(0, "\r\n");
#if SUPPORT_H264MV_MD
            // H264 2 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                PCAM_USB_ResetSlotBuf(1, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
            }
            else {
                glPCCAM_VIDEO_BUF_MAX_SIZE = 80*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264 1",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(1, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            }
            RTNA_DBG_Str(0, "  ** 2nd H264 wWidth = ");       
            MMPF_DBG_Int(PIPE_INFO(1,w), -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(PIPE_INFO(1,h), -4);
            RTNA_DBG_Str(0, "\r\n");
#endif
            // H264 2 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                PCAM_USB_ResetSlotBuf(1, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
            }
            else {
                glPCCAM_VIDEO_BUF_MAX_SIZE = 80*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264 1",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(1, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            }
            RTNA_DBG_Str(0, "  ** 2nd H264 wWidth = ");       
            MMPF_DBG_Int(PIPE_INFO(1,w), -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(PIPE_INFO(1,h), -4);
            RTNA_DBG_Str(0, "\r\n");
            // MJPEG , 2 slot, Frame Src Buffer from CHIP
            glPCCAM_VIDEO_BUF_MAX_SIZE = PIPE_INFO(2,w) * PIPE_INFO(2,h) / 2;
            if(glPCCAM_VIDEO_BUF_MAX_SIZE < ( 320*240/2 ) )
                glPCCAM_VIDEO_BUF_MAX_SIZE = 320*240/2;
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("MJPEG",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            PCAM_USB_ResetSlotBuf(2, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            
            dbg_printf(3, "JPEG Buf = x%X, SlotSize = x%X\r\n", glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #if SUPPORT_AIT845x_MD
            //**** for send MD data ****//
            glPCCAM_VIDEO_BUF_MAX_SIZE = 16*12 + FRAME_PAYLOAD_HEADER_SZ;
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("M",1*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            PCAM_USB_ResetSlotBuf(PIPE_M, 1, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            //**************************//
            #endif
            #if (SUPPORT_AIT845x_MD || RAW_DATA_EN) && (!(CUSTOMER==ANW))
            if((PIPE_INFO(0,h)==720)||(PIPE_INFO(0,h)==360)||(PIPE_INFO(0,h)==180)||(PIPE_INFO(0,h)==90))
                MD_x_res = 320;
            else
                MD_x_res = 240;
            #endif
            #if((CUSTOMER==ANW) && Y_DATA_EN)
            if((PIPE_INFO(0,h)==720)||(PIPE_INFO(0,h)==360)||(PIPE_INFO(0,h)==180)||(PIPE_INFO(0,h)==90))
                MD_y_res = 180;
            else
                MD_y_res = 240;
            #endif
            #if Y_DATA_EN
            // Y , 2 slot, Frame Src Buffer from CHIP
            #if SUPPORT_AIT845x_MD
            glPCCAM_VIDEO_BUF_MAX_SIZE = MD_x_res * MD_y_res + FRAME_PAYLOAD_HEADER_SZ;
            #else
            glPCCAM_VIDEO_BUF_MAX_SIZE = PIPE_INFO(1,w) * PIPE_INFO(1,h) + FRAME_PAYLOAD_HEADER_SZ;
            #endif
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("Y",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            PCAM_USB_ResetSlotBuf(PIPE_G, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            //MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);

            dbg_printf(3, "Y Buf = x%X, SlotSize = x%X\r\n", glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #endif
            #if RAW_DATA_EN
            #if RAW_PROC_10_BIT_EN
            glPCCAM_VIDEO_BUF_MAX_SIZE = 320*180*4/3 + FRAME_PAYLOAD_HEADER_SZ;
            #else
            #if (CUSTOMER == ANW)&&BIND_SENSOR_OV9710
            glPCCAM_VIDEO_BUF_MAX_SIZE = 320*200 + FRAME_PAYLOAD_HEADER_SZ;
            #else
            glPCCAM_VIDEO_BUF_MAX_SIZE = 320*180 + FRAME_PAYLOAD_HEADER_SZ;
            #endif
            #endif
            glRawBuffer    = glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;	 
            glRawStartAddr = glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("RAW",1*glPCCAM_VIDEO_BUF_MAX_SIZE,32);           
            PCAM_USB_ResetSlotBuf(PIPE_G, 1, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            dbg_printf(3, "RAW Buf = x%X, SlotSize = x%X\r\n", glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #if SUPPORT_PIPE_Y
            glPCCAM_VIDEO_BUF_MAX_SIZE = MD_x_res*MD_y_res + FRAME_PAYLOAD_HEADER_SZ;
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;	 
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("Y",1*glPCCAM_VIDEO_BUF_MAX_SIZE,4096);
            #if (DYNAMIC_CONFIG_CACHEBUF == 1)
            MMPF_MMU_ConfigWorkingBuffer(glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_ADDR+glPCCAM_VIDEO_BUF_MAX_SIZE, TRUE);
            #endif
            PCAM_USB_ResetSlotBuf(PIPE_Y, 1, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            dbg_printf(3, "Y Buf = x%X, SlotSize = x%X\r\n", glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #endif
            #endif
            #if SUPPORT_AIT845x_MD
            #if (CUSTOMER == ANW)
            {
                extern MMP_UBYTE MD_x_div, MD_y_div, MD_sensitivity;//x_max:10 y_max:10
                extern MMP_ULONG MD_address;            //for XU command reset MD address
                extern MMP_USHORT MD_Block[25], MD_BlockTmp[25];
                MD_params_in_t MD_prs = {0, 5, 100, 90, 2000};
                MMP_ULONG mdbufsize=0, mdbufaddr=0, i=0;
                mdbufsize = MD_get_buffer_info(MD_x_res, MD_y_res, 1/*1:Y only*/, MD_x_div, MD_y_div);
                MD_address = mdbufaddr = (MMP_ULONG)MMPF_SYS_AllocFB("MD",mdbufsize,4096);
                #if (DYNAMIC_CONFIG_CACHEBUF == 1)
                MMPF_MMU_ConfigWorkingBuffer(mdbufaddr, mdbufaddr+mdbufsize, TRUE);
                #endif
                MD_init((MMP_UBYTE *)mdbufaddr, mdbufsize, MD_x_res, MD_y_res, 1/*1:Y only*/);
                MD_set_detect_window(0, 0, MD_x_res-1, MD_y_res-1, MD_x_div, MD_y_div);
                MD_prs.sensitivity = MD_sensitivity;
                for(i=0;i<25;i++) {
                    if(MD_Block[i])
                        MD_prs.enable = 1;
                    else
                        MD_prs.enable = 0;
                    MD_set_window_params_in((i%5)*2  , (i/5)*2  , &MD_prs);
                    MD_set_window_params_in((i%5)*2  , (i/5)*2+1, &MD_prs);
                    MD_set_window_params_in((i%5)*2+1, (i/5)*2  , &MD_prs);
                    MD_set_window_params_in((i%5)*2+1, (i/5)*2+1, &MD_prs);
                    MD_BlockTmp[i] = MD_Block[i];
                }
            }
            #else
            {
                extern MMP_UBYTE MD_x_div, MD_y_div;    //x_max:16 y_max:12
                extern MMP_ULONG MD_address;            //for XU command reset MD address
                extern MMP_ULONG MD_sensitivity_number[16*12+1], MD_sensitivity_data[16*12]; //for MD setting before preview
                MD_params_in_t MD_prs = {1, 5, 100, 90, 2000};
                MMP_ULONG mdbufsize=0, mdbufaddr=0, i=0, j=0;
                mdbufsize = MD_get_buffer_info(MD_x_res, MD_y_res, 1/*1:Y only*/, MD_x_div, MD_y_div);
                MD_address = mdbufaddr = (MMP_ULONG)MMPF_SYS_AllocFB("MD",mdbufsize,4096);
                #if (DYNAMIC_CONFIG_CACHEBUF == 1)
                MMPF_MMU_ConfigWorkingBuffer(mdbufaddr, mdbufaddr+mdbufsize, TRUE);
                #endif
                MD_init((MMP_UBYTE *)mdbufaddr, mdbufsize, MD_x_res, MD_y_res, 1/*1:Y only*/);
                MD_set_detect_window(0, 0, MD_x_res-1, MD_y_res-1, MD_x_div, MD_y_div);
                if(MD_sensitivity_number[0]) {
                    //for XU command setting by before preview
                    MD_sensitivity_number[0] &= ~0x8000;
                    for(i=0; i<MD_sensitivity_number[0]; i++) {
                        MD_prs.sensitivity = MD_sensitivity_data[i];
                        if(MD_prs.sensitivity==0)
                            MD_prs.enable = 0;
                        else
                            MD_prs.enable = 1;
                        MD_set_window_params_in(MD_sensitivity_number[i+1]%MD_x_div, MD_sensitivity_number[i+1]/MD_x_div, &MD_prs);
                        j++;
                    }
                    MD_sensitivity_number[0] = 0;
                    for(i=0; i<j; i++) {
                        MD_sensitivity_data[i] = 0;
                        MD_sensitivity_number[i+1] = 0;
                    }
                }
                else {
                    for(i=0; i<(MD_x_div*MD_y_div); i++) {
                        //for init md params in
                        MD_set_window_params_in(i%MD_x_div, i/MD_x_div, &MD_prs);
                    }
                }
            }
            #endif
            #endif
#if (SUPPORT_MP4) || (SUPPORT_MTS)
            if(MMPF_VIDMGR_GetMtsMuxModeEnable() || MMPF_VIDMGR_GetMP4Enable())
            {
                glPCCAM_VIDEO_BUF_MAX_SIZE = (1504*2+32);
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("AUDIO",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(PIPE_AUD, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
                dbg_printf(3, "AUDIO Buf = x%X, SlotSize = x%X\r\n", glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            }
#endif            
	    }
#endif

#if USB_FRAMEBASE_DUAL_H264_STREAM
        else if(gbCurH264Type==FRAMEBASE_DUAL_H264) {
            // H264 1 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                PCAM_USB_ResetSlotBuf(0, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
            }
            else {
                glPCCAM_VIDEO_BUF_MAX_SIZE = 160*1024;//64*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264 0",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(0, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            }
            RTNA_DBG_Str(0, "  ** 1nd H264 wWidth = ");       
            MMPF_DBG_Int(PIPE_INFO(0,w), -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(PIPE_INFO(0,h), -4);
            RTNA_DBG_Str(0, "\r\n");
                
            // H264 2 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                PCAM_USB_ResetSlotBuf(1, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
            }
            else {
                glPCCAM_VIDEO_BUF_MAX_SIZE = 160*1024;//64*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264 1",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(1, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            }
            RTNA_DBG_Str(0, "  ** 2nd H264 wWidth = ");       
            MMPF_DBG_Int(PIPE_INFO(1,w), -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(PIPE_INFO(1,h), -4);
            RTNA_DBG_Str(0, "\r\n");
            
	    }
        else if(gbCurH264Type==FRAMEBASE_DUAL_H264_MJPEG) {
            #if SUPPORT_AIT845x_MD || RAW_DATA_EN
            #if (DYNAMIC_CONFIG_CACHEBUF == 1)
            extern void MMPF_MMU_ConfigWorkingBuffer(unsigned int startAddr, unsigned int endAddr, char cacheable);
            #endif
            extern MMP_USHORT MD_x_res, MD_y_res;
            #endif
            // H264 1 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                PCAM_USB_ResetSlotBuf(0, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
            }
            else {
                glPCCAM_VIDEO_BUF_MAX_SIZE = 100*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264 0",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(0, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            }
            RTNA_DBG_Str(0, "  ** 1nd H264 wWidth = ");       
            MMPF_DBG_Int(PIPE_INFO(0,w), -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(PIPE_INFO(0,h), -4);
            RTNA_DBG_Str(0, "\r\n");
                
            // H264 2 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                PCAM_USB_ResetSlotBuf(1, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
            }
            else {
                glPCCAM_VIDEO_BUF_MAX_SIZE = 60*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264 1",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(1, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            }
            RTNA_DBG_Str(0, "  ** 2nd H264 wWidth = ");       
            MMPF_DBG_Int(PIPE_INFO(1,w), -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(PIPE_INFO(1,h), -4);
            RTNA_DBG_Str(0, "\r\n");
            
            // MJPEG , 2 slot, Frame Src Buffer from CHIP
            glPCCAM_VIDEO_BUF_MAX_SIZE = PIPE_INFO(0,w) * PIPE_INFO(0,h) / 4;   //for jpeg capture 720p buffer
            if(glPCCAM_VIDEO_BUF_MAX_SIZE < ( 320*240/4 ) )
                glPCCAM_VIDEO_BUF_MAX_SIZE = 320*240/4;
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("MJPEG",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            PCAM_USB_ResetSlotBuf(2, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            
            dbg_printf(3, "JPEG Buf = x%X, SlotSize = x%X\r\n", glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);

            #if SUPPORT_AIT845x_MD
            //**** for send MD data ****//
            glPCCAM_VIDEO_BUF_MAX_SIZE = 16*12 + FRAME_PAYLOAD_HEADER_SZ;
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("M",1*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            PCAM_USB_ResetSlotBuf(PIPE_M, 1, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            //**************************//
            #endif
            #if SUPPORT_AIT845x_MD || RAW_DATA_EN
            if((PIPE_INFO(0,h)==720)||(PIPE_INFO(0,h)==360)||(PIPE_INFO(0,h)==180)||(PIPE_INFO(0,h)==90))
                MD_x_res = 320;
            else
                MD_x_res = 240;
            #endif
            #if Y_DATA_EN
            // Y , 2 slot, Frame Src Buffer from CHIP
            #if SUPPORT_AIT845x_MD
            glPCCAM_VIDEO_BUF_MAX_SIZE = MD_x_res * MD_y_res + FRAME_PAYLOAD_HEADER_SZ;
            #else
            glPCCAM_VIDEO_BUF_MAX_SIZE = PIPE_INFO(1,w) * PIPE_INFO(1,h) + FRAME_PAYLOAD_HEADER_SZ;
            #endif
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("Y",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            PCAM_USB_ResetSlotBuf(PIPE_G, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            //MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);

            dbg_printf(3, "Y Buf = x%X, SlotSize = x%X\r\n", glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #endif
            #if RAW_DATA_EN
            #if RAW_PROC_10_BIT_EN
            glPCCAM_VIDEO_BUF_MAX_SIZE = 320*180*4/3 + FRAME_PAYLOAD_HEADER_SZ;
            #else
            glPCCAM_VIDEO_BUF_MAX_SIZE = 320*180 + FRAME_PAYLOAD_HEADER_SZ;
            #endif
            glRawBuffer    = glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;	 
            glRawStartAddr = glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("RAW",1*glPCCAM_VIDEO_BUF_MAX_SIZE,32);           
            PCAM_USB_ResetSlotBuf(PIPE_G, 1, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            dbg_printf(3, "RAW Buf = x%X, SlotSize = x%X\r\n", glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #if SUPPORT_PIPE_Y
            glPCCAM_VIDEO_BUF_MAX_SIZE = MD_x_res*MD_y_res + FRAME_PAYLOAD_HEADER_SZ;
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;	 
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("Y",1*glPCCAM_VIDEO_BUF_MAX_SIZE,4096);
            #if (DYNAMIC_CONFIG_CACHEBUF == 1)
            MMPF_MMU_ConfigWorkingBuffer(glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_ADDR+glPCCAM_VIDEO_BUF_MAX_SIZE, TRUE);
            #endif
            PCAM_USB_ResetSlotBuf(PIPE_Y, 1, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            dbg_printf(3, "Y Buf = x%X, SlotSize = x%X\r\n", glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #endif
            #endif
            #if SUPPORT_AIT845x_MD
            {
                extern MMP_UBYTE MD_x_div, MD_y_div;    //x_max:16 y_max:12
                extern MMP_ULONG MD_address;            //for XU command reset MD address
                extern MMP_ULONG MD_sensitivity_number[16*12+1], MD_sensitivity_data[16*12]; //for MD setting before preview
                MD_params_in_t MD_prs = {1, 5, 100, 90, 2000};
                MMP_ULONG mdbufsize=0, mdbufaddr=0, i=0, j=0;
                mdbufsize = MD_get_buffer_info(MD_x_res, MD_y_res, 1/*1:Y only*/, MD_x_div, MD_y_div);
                MD_address = mdbufaddr = (MMP_ULONG)MMPF_SYS_AllocFB("MD",mdbufsize,4096);
                #if (DYNAMIC_CONFIG_CACHEBUF == 1)
                MMPF_MMU_ConfigWorkingBuffer(mdbufaddr, mdbufaddr+mdbufsize, TRUE);
                #endif
                MD_init((MMP_UBYTE *)mdbufaddr, mdbufsize, MD_x_res, MD_y_res, 1/*1:Y only*/);
                MD_set_detect_window(0, 0, MD_x_res-1, MD_y_res-1, MD_x_div, MD_y_div);
                if(MD_sensitivity_number[0]) {
                    //for XU command setting by before preview
                    MD_sensitivity_number[0] &= ~0x8000;
                    for(i=0; i<MD_sensitivity_number[0]; i++) {
                        MD_prs.sensitivity = MD_sensitivity_data[i];
                        if(MD_prs.sensitivity==0)
                            MD_prs.enable = 0;
                        else
                            MD_prs.enable = 1;
                        MD_set_window_params_in(MD_sensitivity_number[i+1]%MD_x_div, MD_sensitivity_number[i+1]/MD_x_div, &MD_prs);
                        j++;
                    }
                    MD_sensitivity_number[0] = 0;
                    for(i=0; i<j; i++) {
                        MD_sensitivity_data[i] = 0;
                        MD_sensitivity_number[i+1] = 0;
                    }
                }
                else {
                    for(i=0; i<(MD_x_div*MD_y_div); i++) {
                        //for init md params in
                        MD_set_window_params_in(i%MD_x_div, i/MD_x_div, &MD_prs);
                    }
                }
            }
            #endif
	    }
#endif

#if (SECS_VER > 20)
        else if(gbCurH264Type==SKYPE_TX_STREAM) {

            RES_TYPE_CFG *cur_res = GetResCfg(pCamCtx.videoRes) ;

            dbg_printf(3, "H.264 %dx%d\r\n", cur_res->res_w, cur_res->res_h);

                
            glPCCAM_VIDEO_BUF_MAX_SIZE =  (cur_res->res_w * cur_res->res_h * 3 )/ 2 ;
            // 1/8 size of YUV420
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE / 8 ) + aligned_header_size;
              
            if(glPCCAM_VIDEO_BUF_MAX_SIZE < ( 320*240*3/2 ) )
                glPCCAM_VIDEO_BUF_MAX_SIZE = 320*240*3/2 ;
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;

            // H264 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 12;
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE/2;
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;     
            }
            else {
            #if DRAM_SIZE <= 2
                glPCCAM_VIDEO_BUF_MAX_SIZE = 64*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(1, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #else
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - aligned_header_size));
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 3 ; // 3 ring buffer 
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;     
            #endif
            }

            #if USE_RESET_SLOT_FUNC == 0
            PIPE_INFO(1,b) = cur_bctl ;
            #endif
            
        #if DRAM_SIZE <= 2//use ring buffer
            glPCCAM_VIDEO_BUF_MAX_SIZE = 80*1024;
        #else
            glPCCAM_VIDEO_BUF_MAX_SIZE = GetYUY2FrameSize(glPccamResolution);    
        #endif
            // Align to 32bytes 
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;
    
            glPCCAM_VIDEO_BUF_MAX_SIZE += aligned_header_size;

            // reserved skype header section
            glPCCAM_VIDEO_BUF_MAX_SIZE += 64;  // YUV header (4 Bytes) + HDR0(20 Bytes) + HDR1(20 Bytes) + header number(4 Bytes) + Magic number(4 Bytes)
        #if DRAM_SIZE <= 2
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("YUY2",glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            PCAM_USB_ResetSlotBuf(0, 1, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        #else            
            // YUY2 , 2 slot, Frame Src Buffer from CHIP
            cur_buf = (MMP_ULONG)MMPF_SYS_AllocFB("YUY2",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            cur_bctl.rd_index = cur_bctl.wr_index = 0;
            cur_bctl.total_rd = cur_bctl.total_wr = 0;
            cur_bctl.slot_num = 2; // 2 ring buffer 
            cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
            cur_bctl.buf_addr =  cur_buf ;     
            PIPE_INFO(0,b) = cur_bctl ;
        #endif
        }
#endif

#if SKYPE_UVC_H264
        else if(gbCurH264Type==UVC_H264_STREAM) {
            //RES_TYPE_CFG *cur_res = GetResCfg(pCamCtx.videoRes) ;

            //UVCX_EnableSliceBasedTx( 0 );
            #if 0
            RTNA_DBG_Str(0, "  ** H264 wWidth = ");       
            MMPF_DBG_Int(cur_res->res_w, -4);
            RTNA_DBG_Str(0, " : ");
            RTNA_DBG_Str(0, "  wHeight = ");       
            MMPF_DBG_Int(cur_res->res_h, -4);
            RTNA_DBG_Str(0, "\r\n");
            #endif
                
            #if DRAM_SIZE > 2
            glPCCAM_VIDEO_BUF_MAX_SIZE =  (cur_res->res_w * cur_res->res_h * 3 )/ 2 ;
            // 1/8 size of YUV420
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE / 10 ) + aligned_header_size;
              
            if(glPCCAM_VIDEO_BUF_MAX_SIZE < ( 320*240*3/2 ) )
                glPCCAM_VIDEO_BUF_MAX_SIZE = 320*240*3/2 ;
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;
            #endif
            // H264 frame buffer
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                #if USE_RESET_SLOT_FUNC
                PCAM_USB_ResetSlotBuf(1, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
                #else
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 12;
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE/2;
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;
                #endif
            }
            else {
            #if DRAM_SIZE == 2
                #if USE_RESET_SLOT_FUNC == 0
                    #error USE_RESET_SLOT_FUNC must be 1 in 8433.
                #endif
                glPCCAM_VIDEO_BUF_MAX_SIZE = 64*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",2*64*1024,32);
                PCAM_USB_ResetSlotBuf(1, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #else
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                //MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - aligned_header_size));
                #if USE_RESET_SLOT_FUNC
                PCAM_USB_ResetSlotBuf(1, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
                #else
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 3 ; // 3 ring buffer 
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;
                #endif
            #endif
            }
            #if USE_RESET_SLOT_FUNC == 0
            PIPE_INFO(1,b) = cur_bctl ;
            #endif

            // YUY2 , 1 slot, Frame Src Buffer from CHIP
        #if DRAM_SIZE == 2
            glPCCAM_VIDEO_BUF_MAX_SIZE = 80*1024;
            glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("YUY2",glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            PCAM_USB_ResetSlotBuf(0, 1, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        #else
            glPCCAM_VIDEO_BUF_MAX_SIZE = GetYUY2FrameSize(glPccamResolution) + aligned_header_size;    
            // Align to 32bytes 
            glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;
    
            // YUY2 , 2 slot, Frame Src Buffer from CHIP
            #if USE_RESET_SLOT_FUNC
            PCAM_USB_ResetSlotBuf(0, 2, cur_buf, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #else
            cur_buf = (MMP_ULONG)MMPF_SYS_AllocFB("YUY2",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
            cur_bctl.rd_index = cur_bctl.wr_index = 0;
            cur_bctl.total_rd = cur_bctl.total_wr = 0;
            cur_bctl.slot_num = 2; // 2 ring buffer 
            cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
            cur_bctl.buf_addr =  cur_buf ;     
            PIPE_INFO(0,b) = cur_bctl ;
            #endif
		#endif
        }
#endif

        else {
            //other gbCurH264Type
            //UVCX_EnableSliceBasedTx( 0 );
        
            if (MMPF_VIDENC_GetOutputSyncMode() == MMPF_VIDENC_OUTPUT_SLICE_SYNC) { //slice based
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",6*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - FRAME_PAYLOAD_HEADER_SZ));
                #if USE_RESET_SLOT_FUNC
                PCAM_USB_ResetSlotBuf(1, 12, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE/2);
                #else
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 12;
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE/2;
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;
                #endif
            }
            else {
            #if DRAM_SIZE == 2
                glPCCAM_VIDEO_BUF_MAX_SIZE = 64*1024;
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                PCAM_USB_ResetSlotBuf(1, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
            #else
                glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("H264",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                #if USE_RESET_SLOT_FUNC
                PCAM_USB_ResetSlotBuf(1, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
                #else
                cur_bctl.rd_index = cur_bctl.wr_index = 0;
                cur_bctl.total_rd = cur_bctl.total_wr = 0;
                cur_bctl.slot_num = 3 ; // 3 ring buffer 
                cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
                cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;
                #endif
            #endif
            }     
            #if USE_RESET_SLOT_FUNC == 0
            PIPE_INFO(1,b) = cur_bctl ;
            #endif
            
            
            if(stream_cfg->pipe_en & PIPE0_EN) {
                if ((GET_PIPE_FORMAT(stream_cfg, 0)) == PIPE_CFG_YUY2) {
                // YUY2
                    
                } else {
                // MJPEG, always 320x240 for test
                #if DRAM_SIZE > 2
                    if (1/*glPccamResolution==PCCAM_320_240*/) {
                        //RTNA_DBG_Str3("FrameBaseH264, JPEG is 320x240\r\n");
                        glPCCAM_VIDEO_BUF_MAX_SIZE = 320 * 240 + aligned_header_size ;
                        
                        glPCCAM_VIDEO_BUF_MAX_SIZE = (glPCCAM_VIDEO_BUF_MAX_SIZE + 31 ) & (-32) ;
                        glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("JPEG",3*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                        #if USE_RESET_SLOT_FUNC
                        PCAM_USB_ResetSlotBuf(0, 3, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
                        #else
                        cur_bctl.rd_index = cur_bctl.wr_index = 0;
                        cur_bctl.total_rd = cur_bctl.total_wr = 0;
                        cur_bctl.slot_num = 3  ; // 3 ring buffer 
                        cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
                        cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;     
                        PIPE_INFO(0,b) = cur_bctl ;
                        #endif
                        // For JPEG 
                        MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR,(glPCCAM_VIDEO_BUF_MAX_SIZE-aligned_header_size));
                    }                
                #else
                    glPCCAM_VIDEO_BUF_MAX_SIZE = ALIGN32(40 * 1024 + aligned_header_size);
                    glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("JPEG",2*glPCCAM_VIDEO_BUF_MAX_SIZE,32);
                    PCAM_USB_ResetSlotBuf(0, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
                    // For JPEG
                    MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR,(glPCCAM_VIDEO_BUF_MAX_SIZE-aligned_header_size));
                #endif
                }
                
            }
        }

#if RAW_DATA_EN
        if(gsFrameDataWithRaw){
            MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_RAWPROC, MMP_TRUE);
            MMPF_RAWPROC_Reset();
            MMPF_RAWPROC_SetRawBuffer(0, glRawStartAddr + aligned_header_size);
            //MMPF_RAWPROC_SetRawBuffer(1, glRawStartAddr + glRawBuffer + aligned_header_size);
            #if (CUSTOMER == ANW)&&BIND_SENSOR_OV9710
            MMPF_RAWPROC_GrabSensorRange(1,320,1,200);
            #else
            MMPF_RAWPROC_GrabSensorRange(1,320,1,180);
            #endif
            MMPF_RAWPROC_SetCaptureStoreAddr();
            MMPF_RAWPROC_EnableDownsample(MMP_TRUE, 4);
            MMPF_RAWPROC_EnableRawPath(MMP_TRUE);
        }
#endif

#if USING_UVCX_VIDEO_CONFIG==1
            dbg_printf(3, "  ** CurH264Config Bitrate = %d, FrameInterval = %d\r\n", UVCX_GetH264StartConfig()->dwBitRate,
                       UVCX_GetH264StartConfig()->dwFrameInterval);
            UVCX_SetH264StartMode(UVCX_GetH264StartConfig());

#if USB_FRAMEBASE_DUAL_H264_STREAM
            if ((gbCurH264Type == FRAMEBASE_DUAL_H264)||(gbCurH264Type == FRAMEBASE_H264)||(gbCurH264Type == FRAMEBASE_DUAL_H264_MJPEG)||
                (gbCurH264Type == FRAMEBASE_H264FRAME_MJPEG)) {
                extern UVCX_VIDEO_CONFIG gsCurH264Config;
                extern MMP_ULONG DualStream_setFPS[3], DualStream_setBR[2];
                extern MMP_UBYTE XU_Ctrl_StreamID;
                MMP_ULONG tmp, i;
                tmp = XU_Ctrl_StreamID;
                for(i=0; i<2; i++) {
                    XU_Ctrl_StreamID = i;
                    //Set framerate before preview for XU command
                    if(DualStream_setFPS[i] != (10000000/gsCurH264Config.dwFrameInterval)) {
                        MMP_ULONG fr_interval;
                        fr_interval = 10000000 / DualStream_setFPS[i];
                        UVCX_SetH264FrameRate(i, fr_interval);
                        dbg_printf(3,"Set H264_%d framerate = %d\r\n", i, DualStream_setFPS[i]);
                    }
                    //Set bitrate before preview for XU command
                    if(DualStream_setBR[i] != 3000000) {
                        UVCX_BitRateLayers br_ctl;
                        br_ctl.wLayerID |= (1 << LAYER_ID_BIT_SHIFT_TEMPORAL);
                        br_ctl.dwAverageBitrate = br_ctl.dwPeakBitrate = DualStream_setBR[i];
                        UVCX_SetH264BitRate(i, &br_ctl);
                        dbg_printf(3,"Set H264_%d bitrate = %d\r\n", i, DualStream_setBR[i]);
                    }
                }
    #if (CUSTOMER == ANW)  // set GOP count if frame rate is not equal to 30
                if(DualStream_setFPS[0] != 30){
                    UVCX_SetH264GOPCount(0, (DualStream_setFPS[0] - 1));
                }
    #endif
                XU_Ctrl_StreamID = tmp;
            }
#endif

            #if DRAM_SIZE > 2
            if(pCamCtx.videoRes==VIDRECD_RESOL_1920x1080) {
                if(gbCurH264Type==FRAMEBASE_H264) {
                    MMPD_H264ENC_SetIMENum(15); 
                } else {
                    MMPD_H264ENC_SetIMENum(3);    
                }
            } else
            #endif
            {
                MMPD_H264ENC_SetIMENum(15);  
            }
//        } else {
//            PCAM_USB_SetH264StartMode();
//            MMPD_H264ENC_SetIMENum(15);
//        }    
#else        
        PCAM_USB_SetH264StartMode();
        MMPD_H264ENC_SetIMENum(15);
#endif
        {
            extern MMP_USHORT       gsSensorPreviewWidth[3];
            extern MMP_USHORT       gsSensorPreviewHeight[3];
            extern MMP_USHORT       gsCurPreviewMode;
            MMP_USHORT              usEncWidth[MAX_VIDENC_NUM], usEncHeight[MAX_VIDENC_NUM];
            MMP_ULONG               stackaddr;
            RES_TYPE_CFG            *cur_res = GetResCfg(pCamCtx.videoRes);
            MMPF_VIDENC_CROPPING    crop_offset = {0, 0, 0, 0};
            MMPF_VIDENC_FRAME_LIST  InputFrameList[2];
            MMPF_VIDENC_CURBUF_MODE_CTL CurCtl = {MMPF_VIDENC_CURBUF_FRAME, 1};
#if USB_FRAMEBASE_DUAL_H264_STREAM
            if ((gbCurH264Type == FRAMEBASE_DUAL_H264) || (gbCurH264Type == FRAMEBASE_DUAL_H264_MJPEG) || (gbCurH264Type == FRAMEBASE_H264FRAME_MJPEG)) {
                usEncWidth[0] = ALIGN16(PIPE_INFO(0,w));
                usEncHeight[0] = ALIGN16(PIPE_INFO(0,h));

                crop_offset.usRight = usEncWidth[0] - PIPE_INFO(0,w);
                crop_offset.usBottom = usEncHeight[0] - PIPE_INFO(0,h);
            } 
            else
#endif
            {
                usEncWidth[0] = ALIGN16(cur_res->res_w);
                usEncHeight[0] = ALIGN16(cur_res->res_h);

                crop_offset.usRight = usEncWidth[0] - cur_res->res_w;
                crop_offset.usBottom = usEncHeight[0] - cur_res->res_h;
            }
            MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_CROPPING, (void*)&crop_offset);

#if DRAM_SIZE == 2
    #if (SUPPORT_OSD_FUNC)
            if(1)
    #elif USB_FRAMEBASE_DUAL_H264_STREAM
            if((gbCurH264Type==FRAMEBASE_DUAL_H264) || (gbCurH264Type==FRAMEBASE_DUAL_H264_MJPEG) || (gbCurH264Type==FRAMEBASE_H264FRAME_MJPEG))
    #else
            if(0)
    #endif
            CurCtl.CurBufMode = MMPF_VIDENC_CURBUF_FRAME;
            else
            CurCtl.CurBufMode = MMPF_VIDENC_CURBUF_RT_SRAM;
#else
            CurCtl.CurBufMode = MMPF_VIDENC_CURBUF_RT_INTLV;
#endif

            MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_CURBUF_MODE, (void*)&CurCtl);
            MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_RINGBUF_EN, (void*)MMP_FALSE);
            MMPF_VIDENC_SetParameter(0, MMPF_VIDENC_ATTRIBUTE_REFGENBUF_MODE, (void*)MMPF_VIDENC_REFGENBUF_ROTATE);

#if USB_FRAMEBASE_DUAL_H264_STREAM
            //Vin: Dual H264 Option
            if((stream_cfg->pipe_en & PIPE1_EN)&&((gbCurH264Type==FRAMEBASE_DUAL_H264)||(gbCurH264Type==FRAMEBASE_DUAL_H264_MJPEG) ||
               (gbCurH264Type==FRAMEBASE_H264FRAME_MJPEG))) {
                cur_res = GetResCfg(glPccamResolution);		
                usEncWidth[1] = ALIGN16(PIPE_INFO(1,w));
                usEncHeight[1] = ALIGN16(PIPE_INFO(1,h));

                crop_offset.usRight = usEncWidth[1] - PIPE_INFO(1,w);
                crop_offset.usBottom = usEncHeight[1] - PIPE_INFO(1,h);
                MMPF_VIDENC_SetParameter(1, MMPF_VIDENC_ATTRIBUTE_CROPPING, (void*)&crop_offset);

                MMPF_VIDENC_SetParameter(1, MMPF_VIDENC_ATTRIBUTE_CURBUF_MODE, (void*)&CurCtl);
                MMPF_VIDENC_SetParameter(1, MMPF_VIDENC_ATTRIBUTE_RINGBUF_EN, (void*)MMP_FALSE);
                MMPF_VIDENC_SetParameter(1, MMPF_VIDENC_ATTRIBUTE_REFGENBUF_MODE, (void*)MMPF_VIDENC_REFGENBUF_ROTATE);
            }
#endif
            //stackaddr = ((MMP_ULONG) MMPF_SYS_GetCurFBAddr() + 1023 )&(-1024);
            stackaddr = ((MMP_ULONG) MMPF_SYS_GetCurFBAddr() + 31 )&(-32);//Truman@120808 This should be good enough to save code size
            #if DRAM_SIZE <= 2
            glEndOfH264SramAddr = 0x100000 + 1 * 1024;
            #endif
            dbg_printf(3, "  == Set H264 memory map begin ==\r\n----H264 FB.Start(SRAM):%08X\r\n----H264 FB.Start(DRAM):%08X\r\n",
                       glEndOfH264SramAddr, stackaddr);
            //dbg_printf(3, "----H264 FB.Start(SRAM):%08X\r\n", glEndOfH264SramAddr);
            //RTNA_DBG_Str3("  == Set H264 memory map begin ==\r\n");
            //RTNA_DBG_Str3("----H264 FB.Start(SRAM) :");RTNA_DBG_Long3(glEndOfH264SramAddr);RTNA_DBG_Str3("\r\n");
            //RTNA_DBG_Str3("----H264 FB.Start(DRAM) :");RTNA_DBG_Long3(stackaddr);RTNA_DBG_Str3("\r\n");
            dbg_printf(3, "%dx%d H.264 0\r\n", usEncWidth[0], usEncHeight[0]);
#if USB_FRAMEBASE_DUAL_H264_STREAM
            if((gbCurH264Type==FRAMEBASE_DUAL_H264) || (gbCurH264Type==FRAMEBASE_DUAL_H264_MJPEG) || (gbCurH264Type==FRAMEBASE_H264FRAME_MJPEG)) {
                dbg_printf(3, "%dx%d H.264 1\r\n", usEncWidth[1], usEncHeight[1]);			
                MMPS_3GPRECD_SetResolution(usEncWidth, usEncHeight, MAX_VIDENC_NUM);
            } else
#endif
            {
                MMPS_3GPRECD_SetResolution(usEncWidth, usEncHeight, 1);
            }
#if (SUPPORT_H264MV_MD)
            if(gbCurH264Type == FRAMEBASE_H264FRAME_MJPEG){
                MMP_USHORT usXMvBd, usYMvBd;
                // Set Motion detection mode
                MMPF_VIDENC_SetParameter(1, MMPF_VIDENC_ATTRIBUTE_FILTER_MODE, (void*)MMPF_VIDENC_FILTER_ME_REF_RECONSTRUCT);
                MMPF_H264ENC_GetMVSrchRngBd(&usXMvBd, &usYMvBd);
                MD_Initialize((int)(ALIGN16(PIPE_INFO(1,w)) >> 4), (int)(ALIGN16(PIPE_INFO(1,h)) >> 4), (int)usXMvBd, (int)usYMvBd); 
                //MD_SetAllAreaMask(TRUE);
                //MD_SetMvThreshold(128, 64);
                //MD_SetCntTh(20);
                MD_SetMDSensitivity(MD_GetMDSensitivity());
            }
#endif
            MMPS_3GPRECD_SetMemoryMapH264(&glEndOfH264SramAddr, &stackaddr, InputFrameList, H264E_RINGBUF_SIZE);
            dbg_printf(3, "gsCurPreviewMode %d, WxH=%dx%d\r\n", gsCurPreviewMode, gsSensorPreviewWidth[gsCurPreviewMode],gsSensorPreviewHeight[gsCurPreviewMode]);
#if (SECS_VER > 20) || USB_FRAMEBASE_H264_ONLY
            if((gbCurH264Type==SKYPE_TX_STREAM)/*||(m_VideoFmt==MMPS_3GPRECD_VIDEO_FORMAT_H264)*/)
            {
            MMPS_3GPRECD_SetPreviewConfig(gsSensorPreviewWidth[gsCurPreviewMode], gsSensorPreviewHeight[gsCurPreviewMode],
                                            usEncWidth[0], usEncHeight[0],
                                            InputFrameList, usb_uvc_get_preview_fctl_link(1),
                                            GetZoomResolution(), 0, MMP_TRUE);
            }else
#endif
            {
#if USB_FRAMEBASE_DUAL_H264_STREAM
                if((gbCurH264Type==FRAMEBASE_DUAL_H264) || (gbCurH264Type==FRAMEBASE_DUAL_H264_MJPEG) || (gbCurH264Type==FRAMEBASE_H264FRAME_MJPEG)) {
                    if((stream_cfg->pipe_en & PIPE0_EN)&&(GET_PIPE_FORMAT(stream_cfg, 0)==PIPE_CFG_H264))
                        MMPS_3GPRECD_SetPreviewConfig(gsSensorPreviewWidth[gsCurPreviewMode], gsSensorPreviewHeight[gsCurPreviewMode],
                                                        PIPE_INFO(0,w), PIPE_INFO(0,h),
                                                        InputFrameList, usb_uvc_get_preview_fctl_link(PIPE_0),
                                                        GetZoomResolution(), 0, MMP_FALSE);
                    if((stream_cfg->pipe_en & PIPE1_EN)&&(GET_PIPE_FORMAT(stream_cfg, 1)==PIPE_CFG_H264))
                        MMPS_3GPRECD_SetPreviewConfig(gsSensorPreviewWidth[gsCurPreviewMode], gsSensorPreviewHeight[gsCurPreviewMode],
                                                        PIPE_INFO(1,w), PIPE_INFO(1,h),
                                                        InputFrameList, usb_uvc_get_preview_fctl_link(PIPE_1),
                                                        GetZoomResolution(), 1, MMP_FALSE);
                } 
                else
#endif
            MMPS_3GPRECD_SetPreviewConfig(gsSensorPreviewWidth[gsCurPreviewMode], gsSensorPreviewHeight[gsCurPreviewMode],
                                            usEncWidth[0], usEncHeight[0],
                                            InputFrameList, usb_uvc_get_preview_fctl_link(1),
                                            GetZoomResolution(), 0, MMP_FALSE);
            }

            MMPD_System_TuneMCIPriority(2);

            MMPF_SYS_SetCurFBAddr((char*)stackaddr);

            dbg_printf(3, "----H264 FB.End(SRAM):%08X\r\n----H264 FB.End(DRAM):%08X\r\n == Set H264 memory map end ==\r\n",
                       glEndOfH264SramAddr, stackaddr);
            //RTNA_DBG_Str3("----H264 FB.End(SRAM) :");RTNA_DBG_Long3(glEndOfH264SramAddr);RTNA_DBG_Str3("\r\n");
            //RTNA_DBG_Str3("----H264 FB.End(DRAM) :");RTNA_DBG_Long3(stackaddr);RTNA_DBG_Str3("\r\n");
            //RTNA_DBG_Str3("  == Set H264 memory map end ==\r\n");
        }
    } 
#if 0    
	else if( pCamCtx.videoFormat == MMPS_3GPRECD_VIDEO_FORMAT_RAW){

		//RTNA_DBG_Str(0,"Start RAW setting...\r\n");
        //RTNA_DBG_Str(0, "  ** Raw Frame Size = ");       
        //RTNA_DBG_Long(0, glPCCAM_VIDEO_BUF_MAX_SIZE);
        //RTNA_DBG_Str(0, "\r\n");
		
    	pGBL->GBL_CLK_EN_2 |= GBL_CLK_RAWPROC ;
		pGBL->GBL_CLK_EN |= GBL_CLK_DMA;
		glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("PCAM",2 * glPCCAM_VIDEO_BUF_MAX_SIZE,32);
		MMPF_SetPCCAMCompressBuf(cur_buf,(glPCCAM_VIDEO_BUF_MAX_SIZE - aligned_header_size));
        cur_bctl.rd_index = cur_bctl.wr_index = 0;
        cur_bctl.total_rd = cur_bctl.total_wr = 0;
        cur_bctl.slot_num = 2 ; // 3 ring buffer 
        cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
        cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;     
        PIPE_INFO(0,b) = cur_bctl ;
        PIPE_INFO(1,b) = cur_bctl ;
		MMPF_RAWPROC_Reset();
		MMPF_RAWPROC_SetRawBuffer(0,glPCCAM_VIDEO_BUF_ADDR + aligned_header_size);
		MMPF_RAWPROC_SetRawBuffer(1,glPCCAM_VIDEO_BUF_ADDR +  glPCCAM_VIDEO_BUF_MAX_SIZE + aligned_header_size);
		//MMPF_RAWPROC_SetRawBuffer(2,glPCCAM_VIDEO_BUF_ADDR +  glPCCAM_VIDEO_BUF_MAX_SIZE*2 + FRAME_PAYLOAD_HEADER_SZ);

        //MMPF_RAWPROC_ConfigRawPathMemory(MMP_ULONG ulAddr1,MMP_ULONG ulAddr2,2);
				
		MMPF_RAWPROC_SetCaptureStoreAddr();		
		MMPF_RAWPROC_EnableRawPath(MMP_TRUE);
	}
#endif
	
    else if( pCamCtx.videoFormat ==MMPS_3GPRECD_VIDEO_FORMAT_MJPEG) {
        //dbg_printf(3,"[!] H264Type=%d, VideoFmt=%d, videoFormat=%d\r\n", gbCurH264Type, m_VideoFmt, pCamCtx.videoFormat);
#if FRAME_SIZE_NEW_PLAN
        glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("MJPEG",2 * glPCCAM_VIDEO_BUF_MAX_SIZE,32);
        // Set 1st MJPEG compression address
        // For JPEG 
        MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR,(glPCCAM_VIDEO_BUF_MAX_SIZE-aligned_header_size));    

        PCAM_USB_ResetSlotBuf(0, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        PCAM_USB_ResetSlotBuf(1, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        PCAM_USB_ResetSlotBuf(2, 2, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
#else
    #if DRAM_SIZE <= 2
        #define SLOT_NUM_SF 3//slot number for single format
    #else
        #define SLOT_NUM_SF 3//slot number for single format
    #endif
        glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("PCAM",SLOT_NUM_SF * glPCCAM_VIDEO_BUF_MAX_SIZE,32);
        // Set 1st MJPEG compression address
        // For JPEG 
        if(pCamCtx.videoFormat ==MMPS_3GPRECD_VIDEO_FORMAT_MJPEG) {
            MMPF_SetPCCAMCompressBuf(glPCCAM_VIDEO_BUF_ADDR,(glPCCAM_VIDEO_BUF_MAX_SIZE-aligned_header_size));    
        }
        #if 1
        PCAM_USB_ResetSlotBuf(0, SLOT_NUM_SF, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        PCAM_USB_ResetSlotBuf(1, SLOT_NUM_SF, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        #else
        cur_bctl.rd_index = cur_bctl.wr_index = 0;
        cur_bctl.total_rd = cur_bctl.total_wr = 0;
        cur_bctl.slot_num = SLOT_NUM_SF ; // 3 ring buffer 
        cur_bctl.slot_size =  glPCCAM_VIDEO_BUF_MAX_SIZE ; 
        cur_bctl.buf_addr =  glPCCAM_VIDEO_BUF_ADDR ;     
        PIPE_INFO(0,b) = cur_bctl ;
        PIPE_INFO(1,b) = cur_bctl ;
        #endif
#endif
        dbg_printf(3,"buf_addr = 0x%x\r\n", glPCCAM_VIDEO_BUF_ADDR);
        
    }else {//YUY2 if( pCamCtx.videoFormat ==MMPS_3GPRECD_VIDEO_FORMAT_YUV422) {
		extern void MMPF_MMU_ConfigWorkingBuffer(unsigned int startAddr, unsigned int endAddr, char cacheable);
        int slotnum = 2;

        if (IS_PIPE_RING(stream_cfg,0)) {
            slotnum = 1;
        }
        glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_AllocFB("YUY2", glPCCAM_VIDEO_BUF_MAX_SIZE * slotnum,32);
        PCAM_USB_ResetSlotBuf(0, slotnum, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        PCAM_USB_ResetSlotBuf(1, slotnum, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        PCAM_USB_ResetSlotBuf(2, slotnum, glPCCAM_VIDEO_BUF_ADDR, glPCCAM_VIDEO_BUF_MAX_SIZE);
        
#ifdef ZDW_BARCODE
        
        //Ken
        //initil Barcode memorys
       
		//bufVGA =  (MMP_UBYTE*)MMPF_SYS_AllocFB("YUY2",640*480,2);
		//PCAM_USB_ResetSlotBuf(1, 1,(MMP_ULONG)bufVGA, 640*480);

#if (DYNAMIC_CONFIG_CACHEBUF == 1)
		MMPF_MMU_ConfigWorkingBuffer((MMP_ULONG)glPCCAM_VIDEO_BUF_ADDR, (MMP_ULONG)glPCCAM_VIDEO_BUF_ADDR+glPCCAM_VIDEO_BUF_MAX_SIZE*slotnum, MMP_TRUE);
#endif

/*
		KK_Initial_MemBank();
		{ //start up wit trigger btn pressed, into download mode
			AITPS_GPIO  pGPIO = AITC_BASE_GPIO;
			MMP_UBYTE uLevel = (pGPIO->GPIO_DATA[1]&0x100)>>8;
			if(uLevel == 1){
				StartLoadUserData();
				StartUpBuzz();
				bReady = TRUE;
			}
		}
*/
		//InitZDWbarcodeReaderIO();

/*        bufVGA =  (MMP_UBYTE*)MMPF_SYS_AllocFB("YUY2",640*480,2);
		PCAM_USB_ResetSlotBuf(1, 1,(MMP_ULONG)bufVGA, 640*480);
		//bufVGA = (MMP_UBYTE*)mxalloc(640*480);
		
		bufDecode =  (MMP_UBYTE*)MMPF_SYS_AllocFB("YUY2",1024,2);
		PCAM_USB_ResetSlotBuf(1, 1,(MMP_ULONG)bufDecode, 1024);        
*/        

		//LED always on
		//GPIO_OutputControl(MMPF_PIO_REG_GPIO42, MMP_TRUE);
		//GPIO_OutputControl(MMPF_PIO_REG_GPIO43, MMP_TRUE);
	
		//KK_InitGammaTable();
	
        #endif
        
    }

    MMPF_Video_Init_Buffer(aligned_off);
            
    MMPD_System_TuneMCIPriority(2); 

    if( pCamCtx.videoFormat ==MMPS_3GPRECD_VIDEO_FORMAT_H264) {
#if (SUPPORT_OSD_FUNC) && (MOVE_OSD_USING_DMA)
    glOSDStartBufAddr = (MMP_ULONG)MMPF_SYS_GetCurFBAddr();
    glOSDBufferSize = 0x8000;  // the maximum size for flexible OSD word number and line number.
    ulSize = AllocateOSDYUVBuffer(glOSDStartBufAddr);
    cur_buf = (MMP_ULONG)MMPF_SYS_AllocFB("OSD Buffer", glOSDBufferSize, 32);
#endif
    }
    #if DRAM_SIZE <= 2
    glPCCAM_VIDEO_BUF_ADDR = (MMP_ULONG)MMPF_SYS_GetCurFBAddr();
   // dbg_printf(2, "final used buffer = x%08X, %d(x%X) left\r\n", glPCCAM_VIDEO_BUF_ADDR,
   //         MAX_DRAM_BUF_ADDR - glPCCAM_VIDEO_BUF_ADDR, MAX_DRAM_BUF_ADDR - glPCCAM_VIDEO_BUF_ADDR);
    #endif
#if 0//def ZDW_BARCODE
        if(bFirstInit == MMP_TRUE)
        {
            bFirstInit = MMP_FALSE;
			KK_Initial_MemBank();
			{ //start up wit trigger btn pressed, into download mode
				AITPS_GPIO  pGPIO = AITC_BASE_GPIO;
				MMP_UBYTE uLevel = (pGPIO->GPIO_DATA[1]&0x100)>>8;
				if(uLevel == 1){
					StartLoadUserData();
					MMPF_OS_Sleep(100);
					StartUpBuzz();
					bReady = TRUE;
				}
			}
        }
#endif

    return PCAM_ERROR_NONE ;
}


MMP_USHORT PCAM_USB_PreviewStop(pcam_msg_t *msg)
{
	//AITPS_GBL   pGBL = AITC_BASE_GBL;
	AITPS_GBL pGBL = AITC_BASE_GBL;
	AITPS_AIC   pAIC = AITC_BASE_AIC;
    extern MMP_BOOL m_bVidRecdPreviewStatus;

    #if (DYNAMIC_CONFIG_CACHEBUF == 1)
    extern void MMPF_MMU_ConfigWorkingBuffer(unsigned int startAddr, unsigned int endAddr, char cacheable);
    MMPF_MMU_ConfigWorkingBuffer(0x1100000, 0x1800000, FALSE);
    #endif

    // sean@2010_09_13, move to here !
    if(m_VideoFmt == PCAM_USB_VIDEO_FORMAT_H264){
        MMPS_3GPRECD_StopRecord();
        //RTNA_DBG_Str3("MMPS_3GPRECD_StopRecord\r\n");
	}
    //RTNA_DBG_Str(3, "USB_VideoPreviewStop()\r\n");
    if (m_bVidRecdPreviewStatus != MMP_FALSE) {
        MMPF_Fctl_EnablePreview(MMPF_IBC_PIPE_0, MMP_FALSE, MMP_FALSE);
        MMPF_Fctl_EnablePreview(MMPF_IBC_PIPE_1, MMP_FALSE, MMP_FALSE);
        MMPD_System_TuneMCIPriority(1);
        MMPD_System_ResetHModule(MMPD_SYSTEM_HMODULETYPE_VI, MMP_TRUE);
        MMPD_System_ResetHModule(MMPD_SYSTEM_HMODULETYPE_IBC, MMP_TRUE);
        MMPD_System_ResetHModule(MMPD_SYSTEM_HMODULETYPE_SCAL, MMP_TRUE);
        MMPD_System_ResetHModule(MMPD_SYSTEM_HMODULETYPE_ISP, MMP_TRUE);
    	MMPF_VIDENC_SoftStop();
    	m_bVidRecdPreviewStatus = MMP_FALSE;
	}
	MMPF_Video_Init_Buffer(0);

// Disable VIF/ISP/IBC in stop preview.
    //RTNA_AIC_IRQ_Dis(pAIC, AIC_SRC_VIF);
    //RTNA_AIC_IRQ_Dis(pAIC, AIC_SRC_ISP);
    //RTNA_AIC_IRQ_Dis(pAIC, AIC_SRC_IBC);   
    //pGBL->GBL_CLK_DIS0 |= /*GBL_CLK_ISP_DIS | GBL_CLK_VI_DIS |*/ GBL_CLK_AUD_DIS | GBL_CLK_JPG_DIS | GBL_CLK_SCAL_DIS;
   // pGBL->GBL_CLK_DIS1 |= GBL_CLK_RAW_DIS | GBL_CLK_H264_DIS | GBL_CLK_ICON_DIS | GBL_CLK_GRA_DIS | GBL_CLK_IBC_DIS | GBL_CLK_MIPI_DIS;
//
    return PCAM_ERROR_NONE ;
}

MMP_USHORT PCAM_USB_UpdateOSD(pcam_msg_t *msg)
{
   
    return PCAM_ERROR_NONE ;
}

MMP_USHORT PCAM_USB_Exit(pcam_msg_t *msg)
{
    AITPS_GBL   pGBL = AITC_BASE_GBL;
#if (BIND_SENSOR_MT9D111)
    extern MMP_SHORT mt9d111_inited;
#endif
// Power down sensor & AIT Hardware module.
    if(gbDevicePowerSavingStatus == 1) {
        //RTNA_DBG_Str(3,"#-0-#\r\n");
        return PCAM_ERROR_NONE;
    }
    RTNA_DBG_Str(3, "Sen.Dwn()\r\n");
    MMPD_Sensor_PowerDown(gbCurrentSensor);

#if 1
#if (BIND_SENSOR_MT9D111)
    if(mt9d111_inited==0)
    {
#endif
    // set software reset block
    pGBL->GBL_RST_REG_EN |= (GBL_REG_JPG_RST |
                             GBL_REG_ICON_IBC_RST | 
                             GBL_REG_SCAL_RST |
                             GBL_REG_VI_RST |
                             GBL_REG_DMA_RST |
                             GBL_REG_H264_RST
                             );
#if (BIND_SENSOR_MT9D111)
    }
#endif
    // set software reset block
	pGBL->GBL_RST_CTL0 |= (GBL_JPG_RST |
							GBL_ICON_IBC_RST |
							GBL_SCAL_RST |
							GBL_VI_RST |
							GBL_DMA_RST |
							GBL_H264_RST);
    RTNA_WAIT_CYCLE(100);

    // set software reset block
    pGBL->GBL_RST_CTL0 &= ~(GBL_JPG_RST |
							GBL_ICON_IBC_RST |
							GBL_SCAL_RST |
							GBL_VI_RST |
							GBL_DMA_RST |
							GBL_H264_RST);
    
#if WATCHDOG_RESET_EN==1  
     pGBL->GBL_RST_REG_EN = 0 ;//GBL_REG_RST_ALL ;
#else
     pGBL->GBL_RST_REG_EN = 0 ;
#endif
    
#endif

    MMPD_System_EnableClocks(PCAM_PREVIEW_CLOCKS, MMP_FALSE);
    /*
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_JPG, MMP_FALSE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_SCAL, MMP_FALSE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_SD, MMP_FALSE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_RAWPROC, MMP_FALSE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_H264, MMP_FALSE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_DMA, MMP_FALSE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_ICON, MMP_FALSE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_IBC, MMP_FALSE);
    MMPD_System_EnableClock(MMPD_SYSTEM_CLK_MODULE_GRA, MMP_FALSE);
    */

    gbDevicePowerSavingStatus = 1; 
    return PCAM_ERROR_NONE ;
}

// Log the latest pan information.        
extern MMP_USHORT gsPanEnd,gsTiltEnd ;

MMP_USHORT PCAM_USB_SetAttrs(pcam_msg_t *msg)
{
    MMP_BOOL IsPreviewEnable;
  //  MMP_USHORT err = PCAM_ERROR_NONE ;
    PCAM_USB_INFO pCamInfo = *(PCAM_USB_INFO *)msg->msg_data; 
#if 0
    RTNA_DBG_Str(3,"PCAM_USB_SetAttrs:");
    RTNA_DBG_Short(3,msg->msg_sub_id);
    RTNA_DBG_Str(3,"\r\n");
#endif
    
    switch(msg->msg_sub_id){
    case PCAM_USB_SETTING_VIDEO_RES:
        pCamCtx.videoRes = PCAM2MMP_Get_Resolution(&pCamInfo) ;
#if 0
    RTNA_DBG_Str(0,"==videoRes:");
    RTNA_DBG_Short(0,pCamCtx.videoRes);
    RTNA_DBG_Str(0,"\r\n");
#endif
        break;
    case PCAM_USB_SETTING_H264_RES:// set uvc h264 resolution
        pCamCtx.videoRes = PCAM2MMP_Get_Resolution(&pCamInfo) ;
        m_usResolType = pCamCtx.videoRes;
        pCamCtx.videoFormat = PCAM2MMP_Get_VideoFormat(&pCamInfo) ;
        m_VideoFmt = pCamCtx.videoFormat ; 
#if 0
    RTNA_DBG_Str(0,"==m_usResolType:");
    RTNA_DBG_Short(0,m_usResolType);
    RTNA_DBG_Str(0," : ");
    RTNA_DBG_Str(0,"m_VideoFmt:");
    RTNA_DBG_Short(0,m_VideoFmt);
    RTNA_DBG_Str(0,"\r\n");
#endif
        break ;
    case PCAM_USB_SETTING_VIDEO_FORMAT:
        pCamCtx.videoFormat = PCAM2MMP_Get_VideoFormat(&pCamInfo);
        m_VideoFmt = pCamCtx.videoFormat ; 
#if 0
    RTNA_DBG_Str(0,"==m_VideoFmt:");
    RTNA_DBG_Short(0,m_VideoFmt);
    RTNA_DBG_Str(0,"\r\n");
#endif
        break ;
    case PCAM_USB_SETTING_VIDEO_QUALITY:
        pCamCtx.videoQuality = PCAM2MMP_Get_Quality(&pCamInfo);
        m_usVideoQuality = pCamCtx.videoQuality ;
#if 0
    RTNA_DBG_Str(0,"==m_usVideoQuality:");
    RTNA_DBG_Short(0,m_usVideoQuality);
    RTNA_DBG_Str(0,"\r\n");
#endif
        break;
    case PCAM_USB_SETTING_DEBAND:
        pCamCtx.debandMode = PCAM2MMP_Get_DebandMode(&pCamInfo);
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) { 
            //gsSensorFunction->MMPF_SetLightFreq_OV2710(pCamCtx.debandMode);
#if 0
            RTNA_DBG_Str3("BAND:");
            RTNA_DBG_Short3(pCamCtx.debandMode);
            RTNA_DBG_Str3("\r\n");
#endif
            if(pCamCtx.debandMode==SENSOR_DSC_DEBAND_60HZ) {
                ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_60HZ);
            } else if (pCamCtx.debandMode==SENSOR_DSC_DEBAND_50HZ) {
                ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_50HZ);
            } else if (pCamCtx.debandMode==SENSOR_DSC_DEBAND_AUTO) {
                ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_AUTO);
            } else if (pCamCtx.debandMode==SENSOR_DSC_DEBAND_60HZ_LIMITEXPO) {
                ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_60HZ_LIMITEXPO);
            } else if (pCamCtx.debandMode==SENSOR_DSC_DEBAND_50HZ_LIMITEXPO) {
                ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_50HZ_LIMITEXPO);
            } else {
                ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_AUTO_LIMITEXPO);
            }
        }
        break ;

#if SUPPORT_UAC
    case PCAM_USB_SETTING_AUDIO_FORMAT:
        pCamCtx.audioFormat = PCAM2MMP_Get_AudioFormat(&pCamInfo);
        break;
#endif
   
    case PCAM_USB_SETTING_SATURATION: // 0 ~ 255 -> -100 ~ 100
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            MMP_SHORT setvalue = PCAM2MMP_Normalize_Value(pCamInfo.pCamSaturation);
            //gsSensorFunction->MMPF_Sensor_SetSaturation(setvalue);
            ISP_IF_F_SetSaturation(setvalue);
        }
        break ;
    case PCAM_USB_SETTING_CONTRAST:// 0 ~ 255 -> -100 ~ 100
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            MMP_SHORT setvalue = PCAM2MMP_Normalize_Value(pCamInfo.pCamContrast) ;
            //gsSensorFunction->MMPF_Sensor_SetContrast(setvalue);
            ISP_IF_F_SetContrast(setvalue);
        }
        break ;
    case PCAM_USB_SETTING_BRIGHTNESS:// 0 ~ 255 -> 0~20
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
#if 1//(CUSTOMER == ASU)
            //GAMMA y
            MMP_SHORT setvalue = PCAM2MMP_Normalize_Value(pCamInfo.pCamBrightness);
            ISP_IF_F_SetBrightness(setvalue);
#else
            //AE target
            MMP_SHORT setvalue = PCAM2MMP_Normalize_EV(pCamInfo.pCamBrightness) ;
            //gsSensorFunction->MMPF_Sensor_SetExposureValue(setvalue);
            ISP_IF_AE_SetEV(setvalue);
#endif
#if 0
            RTNA_DBG_Str3("  Brightness = ");
            RTNA_DBG_Short3(setvalue);
            RTNA_DBG_Str3("\r\n");
#endif
        }
        break ;
    case PCAM_USB_SETTING_HUE: // -180 ~ 180 -> -100 ~ 100
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            MMP_SHORT setvalue = PCAM2MMP_Normalize_HUE(pCamInfo.pCamHue) ;
           // gsSensorFunction->MMPF_Sensor_SetHue(setvalue);
           ISP_IF_F_SetHue(setvalue);
        }
        break ;
    case PCAM_USB_SETTING_GAMMA: // 1 ~ 255 -> -100 ~ 100
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            MMP_SHORT setvalue = PCAM2MMP_Normalize_Value(pCamInfo.pCamGamma);
            //gsSensorFunction->MMPF_Sensor_SetGamma(setvalue);
            ISP_IF_F_SetGamma(setvalue);
        }
        break ;
    case PCAM_USB_SETTING_BACKLIGHT:
         MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
           // 842ooxx  
           // gsSensorFunction->MMPF_Sensor_SetBacklight(pCamInfo.pCamBacklight);
            //dbg_printf(3, "WDR = 0x%x\r\n", pCamInfo.pCamBacklight);
            if(pCamInfo.pCamBacklight) {
                extern MMP_ULONG glIRCutStatus;
                ISP_IF_AE_SetEV(-25);
                ISP_IF_F_SetWDR(255);
                if(glIRCutStatus==2)    //If IRCut En, then WDR use night mode IQ setting
                ISP_IF_IQ_SetSysMode(0);
                else
                ISP_IF_IQ_SetSysMode(2);
            } else {
                ISP_IF_AE_SetEV(0);
                ISP_IF_F_SetWDR(0);
                ISP_IF_IQ_SetSysMode(1);
            }
        }
        break ;
    case PCAM_USB_SETTING_SHARPNESS: // 0 ~ 255 -> -100 ~ 100
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            MMP_SHORT setvalue =  PCAM2MMP_Normalize_Value(pCamInfo.pCamSharpness);
           // gsSensorFunction->MMPF_Sensor_SetSharpness(setvalue);
           ISP_IF_F_SetSharpness(setvalue);
        }
        break ;
    case PCAM_USB_SETTING_GAIN: // 0 ~ 255 -> 64 ~ 511
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            MMP_SHORT setvalue =  PCAM2MMP_Normalize_Gain(pCamInfo.pCamGain);
            //ISP_IF_SNR_SetAGain(setvalue);  // modify wrong parameter from pCamInfo.pCamGain to setvalue
            gsSensorFunction->MMPF_Sensor_SetSensorGain(setvalue);  // modify wrong parameter from pCamInfo.pCamGain to setvalue
            //ISP_IF_SNR_SetDGain(pCamInfo.pCamGain);
#if 0
            RTNA_DBG_Str3("  pCamGain = ");
            RTNA_DBG_Short3(setvalue);
            RTNA_DBG_Str3("\r\n");
#endif
        }
        break ;
            
    case PCAM_USB_SETTING_WB:
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            gsSensorFunction->MMPF_Sensor_SetAWBEnable(pCamInfo.pCamWB);  
        }
                
        break;
    case PCAM_USB_SETTING_LENS:
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            gsSensorFunction->MMPF_Sensor_SetAFPosition(pCamInfo.pCamLensPos);
            //ISP_IF_MOTOR_GoToAFPos();    
            //RTNA_DBG_Str(3, "  ISP_IF_MOTOR_GoToAFPos()\r\n");       
        }
        break ;
    case PCAM_USB_SETTING_AF:
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable && pCamInfo.pCamEnableAF) {
            ISP_IF_AF_Control(ISP_AF_START);
            //RTNA_DBG_Str(3, "  ISP_IF_AF_Control()\r\n");       
        }
        break;
    case PCAM_USB_SETTING_AE:
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable ) {
            gsSensorFunction->MMPF_Sensor_SetAEEnable(pCamInfo.pCamEnableAE);
        }
        break;
    case PCAM_USB_SETTING_WB_TEMP:
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
#if 0
            RTNA_DBG_Str3("  pCamWBTemp = ");
            RTNA_DBG_Short3(pCamInfo.pCamWBTemp);
            RTNA_DBG_Str3("\r\n");
#endif
            ISP_IF_AWB_SetColorTemp(pCamInfo.pCamWBTemp);
                
        }
        break;
    case PCAM_USB_SETTING_EV:
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable ) {
            //ISP_IF_SNR_SetShutter((pCamInfo.pCamAEExposureValue * 2), ISP_IF_AE_GetVsync());
            gsSensorFunction->MMPF_Sensor_SetSensorShutter((pCamInfo.pCamAEExposureValue * 2), ISP_IF_AE_GetVsync());
        }
        break;
    case PCAM_USB_SETTING_DIGZOOM:
#if SUPPORT_DIGITAL_ZOOM    
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            PCAM_USB_ZOOM  *zoomInfo = &pCamInfo.pCamDigZoom ;
            MMP_USHORT target_val;
        
            SetVideoZoomByJump(zoomInfo, pCamVCCfg.pCamEnableAsyncMode);

            if(pCamVCCfg.pCamEnableAsyncMode) {
                RTNA_DBG_Str(3,"Asnc.Ack 1\r\n");
                // sean@2010_08_31 , what value we need to return ?
                target_val =  ( zoomInfo->Dir==0 )? zoomInfo->RangeMax : zoomInfo->RangeMin ;
                RTNA_DBG_Str3("Asnc.Ack 1:");RTNA_DBG_Short3(target_val);RTNA_DBG_Str3("\r\n");
                usb_vc_update_async_mode(pCamVCCfg.pCamOriginator,pCamVCCfg.pCamSelector,pCamVCCfg.pCamAttribute,&target_val,2);   
            }
                
        } else {
            if(pCamVCCfg.pCamEnableAsyncMode) {
                MMP_USHORT target_val;
                PCAM_USB_ZOOM  *zoomInfo = &pCamInfo.pCamDigZoom ;
                
                // sean@2010_08_31 , what value we need to return ?
                target_val =  ( zoomInfo->Dir==0 )? zoomInfo->RangeMax : zoomInfo->RangeMin ;
                RTNA_DBG_Str3("Asnc.Ack 2:");RTNA_DBG_Short3(target_val);RTNA_DBG_Str3("\r\n");
                usb_vc_update_async_mode(pCamVCCfg.pCamOriginator,pCamVCCfg.pCamSelector,pCamVCCfg.pCamAttribute,&target_val,2);   
            }
        
        }
#endif        
        break;
    case PCAM_USB_SETTING_DIGPAN:
#if SUPPORT_DIGITAL_PAN    
        MMPS_3GPRECD_GetPreviewDisplay(&IsPreviewEnable);
        if(IsPreviewEnable) {
            PCAM_USB_PANTILT  *panInfo = &pCamInfo.pCamDigPan ;

            SetVideoPanTiltByJump(&pCamInfo.pCamDigPan, pCamVCCfg.pCamEnableAsyncMode);

            
//pantilt_reply:            
            if(pCamVCCfg.pCamEnableAsyncMode) {
                MMP_LONG    target_val[2] ;
                target_val[0] = panInfo->PanMax;
                target_val[1] = panInfo->TiltMax;
                //RTNA_DBG_Str3("Notify.UVC\r\n");
                usb_vc_update_async_mode(pCamVCCfg.pCamOriginator,pCamVCCfg.pCamSelector,pCamVCCfg.pCamAttribute,target_val,8);   
            }
        } else {
            PCAM_USB_PANTILT  *panInfo = &pCamInfo.pCamDigPan ;
            MMP_LONG    target_val[2];
            target_val[0] = panInfo->PanMax;
            target_val[1] = panInfo->TiltMax;
            if(pCamVCCfg.pCamEnableAsyncMode) {
                usb_vc_update_async_mode(pCamVCCfg.pCamOriginator,pCamVCCfg.pCamSelector,pCamVCCfg.pCamAttribute,target_val,8);   
            }
            
        }
#endif        
        break;
    }  
//exit_attr:       
    // Change to sync. mode
    pCamVCCfg.pCamEnableAsyncMode = 0 ;
               
    //RTNA_DBG_Str(3,"PCAM_USB_SetAttrs end\r\n");
    return PCAM_ERROR_NONE ;
}


MMP_USHORT PCAM_USB_TakePicture(pcam_msg_t *msg)
{
    return PCAM_ERROR_NONE  ;
}

#if SUPPORT_UAC

extern MMP_ULONG audio_time;
extern MMP_UBYTE gbAud1stInToken  ;
MMP_USHORT gsAudioPreviewStartEnable=0;
extern MMP_UBYTE gbUACAudioStartFlagSet;
extern MMP_UBYTE gbUACAudioStopFlagSet;
extern MMP_UBYTE gbUACAudioSetSampleRateFlagSet;
MMP_UBYTE glAudioWorkingMode = 0x0;

void PCAM_USB_SetAudioWorkMode(MMP_UBYTE mode, MMP_UBYTE status)
{        
    glAudioWorkingMode = SET_AUDIO_WORK_MODE(glAudioWorkingMode, mode, status);
}

MMPF_AUDIO_WORK_MODE_STATUS PCAM_USB_GetAudioWorkMode(MMP_UBYTE mode)
{  
    return GET_AUDIO_WORK_STATUS(glAudioWorkingMode, mode);
}

MMP_USHORT PCAM_USB_AudioStart(pcam_msg_t *msg)
{
    MMP_USHORT err = PCAM_ERROR_NONE ;
	MMP_USHORT audin = I2S_IN ;
    
    PCAM_AUDIO_CFG *pcam_audio = (PCAM_AUDIO_CFG *)msg->msg_data;
    AITPS_AIC   pAIC = AITC_BASE_AIC;
    AITPS_GBL   pGBL = AITC_BASE_GBL;

    //MMP_UBYTE prio_err,old_prio,new_prio;
    MMP_UBYTE uac_flag=0, ts_mp4_flag=0;

    uac_flag = (PCAM_USB_GetAudioWorkMode(MMPF_AUDIO_WORK_MODE_UAC) == MMPF_AUDIO_WORK_STATUS_SEND) ? 1 : 0;
    if(uac_flag)
    {
        PCAM_USB_SetAudioWorkMode(MMPF_AUDIO_WORK_MODE_UAC, MMPF_AUDIO_WORK_STATUS_PROC);
    }
    
    ts_mp4_flag = (PCAM_USB_GetAudioWorkMode(MMPF_AUDIO_WORK_MODE_TS_MP4) == MMPF_AUDIO_WORK_STATUS_SEND) ? 1 : 0;
    if(ts_mp4_flag)
    {
        PCAM_USB_SetAudioWorkMode(MMPF_AUDIO_WORK_MODE_TS_MP4, MMPF_AUDIO_WORK_STATUS_PROC);    
    }
    
    dbg_printf(0, "[UAC:%d, TS:%d]",uac_flag, ts_mp4_flag);

    //prio_err = MMPF_OS_ChangePrio(20,&old_prio,&new_prio);

    RTNA_DBG_Str(3, "PCAM_USB_AudioStart()\r\n");

   // ISP_IF_3A_Control(ISP_3A_PAUSE);
	//MMPF_Sensor_3A_SetInterrupt(0);

	#if (MicSource==MicInPathI2S)

    	#if ((CUSTOMER == CCN) && (MODEL == 0)) 
        GPIO_OutputControl(WM_PWR_EN, TRUE);  // turn on WM8737 ADC
        //MMPF_OS_Sleep(200);
        #endif

    	#if ((CUSTOMER == LGT) && (MODEL == 0)) 
        GPIO_OutputControl(WM_PWR_EN, TRUE);  // turn on WM8737 ADC
        //MMPF_OS_Sleep(200);
        #endif

    	#if ((CUSTOMER == CCN) && (MODEL == 1)) || ((CUSTOMER == LGT) && (MODEL == 1)) 
        GPIO_OutputControl(CNX_PWR_EN, TRUE);
        GPIO_OutputControl(CAM_EN, TRUE);  // for LED control
        
        //GPIO_OutputControl(CNX_RST, FALSE);
        GPIO_OutputControl(CNX_RST, TRUE);
        MMPF_OS_Sleep(200);
        #endif

    	#if (CUSTOMER == LIT)
        GPIO_OutputControl(CNX_PWR_EN, TRUE);
        
        //GPIO_OutputControl(CNX_RST, FALSE);
        GPIO_OutputControl(CNX_RST, TRUE);
        MMPF_OS_Sleep(200);
        #endif
        
    	#if (CUSTOMER == NKT) 
        GPIO_OutputControl(CNX_PWR_EN, TRUE);
        //GPIO_OutputControl(AMP_CTRL, TRUE);
        #endif
        
        #if ((CUSTOMER == ANW) && (AUDEXT_DAC == CX20709))
        //GPIO_OutputControl(CNX_RST, FALSE);
        //MMPF_OS_Sleep(10);
        GPIO_OutputControl(CNX_RST, TRUE);
        MMPF_OS_Sleep(100);
        #endif
		
        #if(BIND_SENSOR_OV5650)&&(AUDEXT_DAC==WM8960)
        {
            extern MMP_UBYTE SEN_AUD_EN;
            if(SEN_AUD_EN==0){
                GPIO_OutputControl(SEN_PWR_EN, MMP_TRUE);
                SEN_AUD_EN=2;
            }else
                SEN_AUD_EN|=2;
        }
        #endif
		
    #endif

    pCamCtx.audioInPath = PCAM2MMP_Get_AudioInPath(pcam_audio) ;
    pCamCtx.lineInChannel = PCAM2MMP_Get_AudioInChannel(pcam_audio) ;

#if 0
    RTNA_DBG_Str3("audioInPath = ");
    RTNA_DBG_Short3(pCamCtx.audioInPath);
    RTNA_DBG_Str3("\r\n");
    RTNA_DBG_Str3("lineInChannel = ");
    RTNA_DBG_Short3(pCamCtx.lineInChannel);
    RTNA_DBG_Str3("\r\n");
#endif
    
    if(pCamCtx.audioInPath==AUDIO_IN_I2S) {
        audin = I2S_IN ;
    }

    pGBL->GBL_CLK_DIS0 &= (~GBL_CLK_AUD_DIS);
    //MMPF_OS_Sleep_MS(5);
        
    //MMPF_SetVoiceInPath(pCamCtx.audioInPath);
    //pGBL->GBL_CLK_DIS0 |= (GBL_CLK_AUD_DIS);

    //MMPF_Audio_SetLineInChannel(pCamCtx.lineInChannel);
    //MMPF_Audio_SetEncodeFormat(VIDEO_AAC_REC_MODE);  //MMPD_AUDIO_VAAC_ENCODE
    //MMPF_Audio_SetEncodeLength(0xffffffff);
    
    // no need !
    #if PCAM_EN==0
    MMPF_3GPMGR_SetAudioAACParam(32000);
    #endif

    RTNA_DBG_Str3("pCamSampleRate = ");
    MMPF_DBG_Int(pcam_audio->pCamSampleRate, -6);
    RTNA_DBG_Str3("\r\n");
    
    //pGBL->GBL_CLK_DIS0 &= (~GBL_CLK_AUD_DIS);
    //MMPF_OS_Sleep_MS(5);

    if(audin==I2S_IN) {
        MMPF_Audio_SetI2SInFormat(1) ; // Set slave

	#if USB_UAC_TO_QUEUE==1
		MMPF_Audio_InitEncoder( ENC_SAMPLES_TIME*((pcam_audio->pCamSampleRate*AUDIN_CHANNEL)/1000) ) ;
	#endif

        MMPF_Audio_InitializeEncodeFIFO(audin, /*ENC_SAMPLES_TIME*/AFE_SAMPLES_TIME*((pcam_audio->pCamSampleRate*AUDIN_CHANNEL)/1000)  /*32*/);
        MMPF_InitAudioSetting(audin, pcam_audio->pCamSampleRate);   //initial iis registers        
        MMPF_Audio_SetMux(audin, 1);

	#if (MicSource == MicInPathI2S)
	    MMPF_Init_ExteralDac((MMP_ULONG)pcam_audio->pCamSampleRate);
	#endif
	        
    #if (AUDEXT_DAC==WM8973) || (AUDEXT_DAC==WM8750) || (AUDEXT_DAC==WM8960)
        PowerUpExtLinIn(pcam_audio->pCamSampleRate);
        MMPC_AudioExtCodec_SetSampleRate(pcam_audio->pCamSampleRate);
    #elif (AUDEXT_DAC==WM8737)
	    MMPF_PowerUpWM8737(pcam_audio->pCamSampleRate) ;
	    //MMPF_OS_Sleep(200);
	#elif (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778)
	    //MMPF_PowerUpCX20709();
	#elif (AUDEXT_DAC == ADC3101)
     	MMPF_PowerUpTLV320ADC3101(pcam_audio->pCamSampleRate) ;
      	MMPC_AudioExtCodec_SetSampleRate(pcam_audio->pCamSampleRate);
	#endif
		
    #if (MicSource == MicInPathI2S)
        // MMPF_EnableAudioDuplex(I2S_DUPLEX,1); //Gason
    #endif
    }    
  

    // Save startup setting.
    gbOrigADCDigitalGain = gbADCDigitalGain  ;

    // enable audio block and audio DAC clock
    if(audin==I2S_IN) {
        RTNA_AIC_IRQ_En(pAIC, AIC_SRC_AUD_FIFO);    
    }

	//ISP_IF_3A_Control(ISP_3A_RECOVER);
	//MMPF_Sensor_3A_SetInterrupt(1);

#if 0
    // ADC related register
	RTNA_DBG_PrintByte(0, REG_BASE_B[0x890C]);
	RTNA_DBG_PrintByte(0, REG_BASE_B[0x89EC]);
#endif

    audio_time = 0;
    if(uac_flag)
	{    
		MMP_USHORT  csr;
		csr = UsbReadTxEpCSR(PCCAM_AU_EP_ADDR);
        csr = csr & TXCSR_RW_MASK;
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr | SET_TX_FLUSHFIFO);
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr | SET_TX_FLUSHFIFO);
		csr = UsbReadTxEpCSR(PCCAM_AU_EP_ADDR) ;
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr & ~TX_UNDERRUN_BIT);
    }

    USB_LEDDisplay(LED_READY, LED_ON);

    if(uac_flag)
    {
    	MMPF_Audio_TimerOpen(UAC_TIMER_MS_LENGTH, MMPF_TIMER_2);
    }

    //prio_err = MMPF_OS_ChangePrio(0,&new_prio,&old_prio);

    glAudioEnable = TRUE;
    gbUACAudioStartFlagSet = FALSE;
	gsAudioPreviewStartEnable = 1;

    RTNA_DBG_Str(3, "PCAM_USB_AudioStart() End\r\n");

    if(uac_flag){
        USB_AudioSetMute(PCAM_API, gbMute);
    }

    if(uac_flag)
    {
        PCAM_USB_SetAudioWorkMode(MMPF_AUDIO_WORK_MODE_UAC, MMPF_AUDIO_WORK_STATUS_DONE);            
        dbg_printf(3, "USB_AUDStart() --> UAC\r\n");
    }
    
    if(ts_mp4_flag)
    {
        PCAM_USB_SetAudioWorkMode(MMPF_AUDIO_WORK_MODE_TS_MP4, MMPF_AUDIO_WORK_STATUS_DONE);            
        dbg_printf(3, "USB_AUDStart() --> TS\r\n");
    }

//#if (MicSource==MicInPathI2S) && (AUDEXT_DAC==WM8737)
//    glAudioCodecInit = TRUE;  // skip first volume setting after audio on for Windows XP
//#endif

    // check if Stop event was detected or not
    if(gbUACAudioStopFlagSet){
        gbUACAudioStopFlagSet = FALSE;
        gbUACAudioSetSampleRateFlagSet = FALSE;
        usb_uac_audio_stop();
    }
    else if(gbUACAudioSetSampleRateFlagSet){
        gbUACAudioSetSampleRateFlagSet = FALSE;
        MMPF_USBCTL_PostMsg(2,TASK_USB_PRIO,USBCTL_MSG_AUDIO_SET_SAMPLERATE,0,(void *)NULL);
    }
    
    return err ;
}

MMP_USHORT PCAM_USB_AudioStop(pcam_msg_t *msg)
{
    MMP_USHORT  err = PCAM_ERROR_NONE ;
    MMP_USHORT  audin = AFE_IN ;
    
    AITPS_AIC   pAIC = AITC_BASE_AIC;
    AITPS_GBL   pGBL = AITC_BASE_GBL;
    volatile MMP_USHORT  i;
    MMP_BOOL uac_en = 0, ts_mp4_en = 0;
    MMP_UBYTE uac_flag=0, ts_mp4_flag=0;

    //RTNA_DBG_Str(3, "USB_AUStop()\r\n");
   
    uac_flag = (PCAM_USB_GetAudioWorkMode(MMPF_AUDIO_WORK_MODE_UAC) == MMPF_AUDIO_WORK_STATUS_SEND) ? 1 : 0;
    if(uac_flag)
    {
        PCAM_USB_SetAudioWorkMode(MMPF_AUDIO_WORK_MODE_UAC, MMPF_AUDIO_WORK_STATUS_PROC);                                        
    }
    
    ts_mp4_flag = (PCAM_USB_GetAudioWorkMode(MMPF_AUDIO_WORK_MODE_TS_MP4) == MMPF_AUDIO_WORK_STATUS_SEND) ? 1 : 0;
    if(ts_mp4_flag)
    {
        PCAM_USB_SetAudioWorkMode(MMPF_AUDIO_WORK_MODE_TS_MP4, MMPF_AUDIO_WORK_STATUS_PROC);                                    
    }
    
    uac_en = (PCAM_USB_GetAudioWorkMode(MMPF_AUDIO_WORK_MODE_UAC) == MMPF_AUDIO_WORK_STATUS_DONE) ? 1 : 0;
    ts_mp4_en = (PCAM_USB_GetAudioWorkMode(MMPF_AUDIO_WORK_MODE_TS_MP4) == MMPF_AUDIO_WORK_STATUS_DONE) ?  1 : 0;

    if(!uac_en){
        MMPF_Audio_TimerClose(MMPF_TIMER_2);
    }
    
    if(!uac_en && !ts_mp4_en){ //All audio functions are disabled.
   
        gbAud1stInToken = 0 ;
    
        if(pCamCtx.audioInPath==AUDIO_IN_I2S) {
            audin = I2S_IN ;
        }

        pGBL->GBL_CLK_DIS0 &= (~GBL_CLK_AUD_DIS);

        for(i = 0;i < 2000;i++)
                ;

        MMPF_Audio_SetMux(audin, 0);
        MMPF_CloseADC();//Gason@ move to here.

        if(audin==I2S_IN) {
            RTNA_AIC_IRQ_Dis(pAIC, AIC_SRC_AUD_FIFO);// copychou add

    	#if (AUDEXT_DAC==WM8737)
            MMPF_PowerDownWM8737();
    	#endif        
		#if (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778)
		    MMPF_PowerDownCX20709();
		#endif
		#if AUDEXT_DAC==ADC3101
        	MMPF_PowerDownTLV320ADC3101();
        #endif
        #if (AUDEXT_DAC==WM8973)
            PowerDownExtMicIn();
        #elif (AUDEXT_DAC==WM8960)
            PowerDownExtDAC();
		#endif

		#if(BIND_SENSOR_OV5650)&&(AUDEXT_DAC==WM8960)
        {
            extern MMP_UBYTE SEN_AUD_EN;
            if(SEN_AUD_EN==2){
                GPIO_OutputControl(SEN_PWR_EN, MMP_FALSE);
                SEN_AUD_EN=0;
            }else
                SEN_AUD_EN&=0xFD;
        }
        #endif

    	#if ((CUSTOMER == CCN) && (MODEL == 0))
            GPIO_OutputControl(WM_PWR_EN, FALSE);  // turn off WM8737 ADC
        #endif

    	#if ((CUSTOMER == LGT) && (MODEL == 0))
            GPIO_OutputControl(WM_PWR_EN, FALSE);  // turn off WM8737 ADC
        #endif

    	#if ((CUSTOMER == CCN) && (MODEL == 1)) || ((CUSTOMER == LGT) && (MODEL == 1)) 
            GPIO_OutputControl(CNX_RST, FALSE);
            GPIO_OutputControl(CNX_PWR_EN, FALSE);
            if(USB_IsPreviewActive() == FALSE) {  // check if video is alive or not for LED control.
                GPIO_OutputControl(CAM_EN, FALSE);
            }
        #endif

        #if ((CUSTOMER == ANW) && (AUDEXT_DAC == CX20709))
        GPIO_OutputControl(CNX_RST, FALSE);
        #endif

    	#if (CUSTOMER == LIT)
            GPIO_OutputControl(CNX_RST, FALSE);
            GPIO_OutputControl(CNX_PWR_EN, FALSE);
        #endif

    	#if (CUSTOMER == NKT) 
            GPIO_OutputControl(CNX_PWR_EN, TRUE);
            //GPIO_OutputControl(AMP_CTRL, FALSE);
        #endif
        
        } else {
            RTNA_AIC_IRQ_Dis(pAIC, AIC_SRC_AUD_FIFO);// copychou add
        }

        pGBL->GBL_CLK_DIS0 |= (GBL_CLK_AUD_DIS);

    }

    if(!uac_en)
    {    
		MMP_USHORT  csr;
		csr = UsbReadTxEpCSR(PCCAM_AU_EP_ADDR);
        csr = csr & TXCSR_RW_MASK;
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr | SET_TX_FLUSHFIFO);
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr | SET_TX_FLUSHFIFO);
		csr = UsbReadTxEpCSR(PCCAM_AU_EP_ADDR) ;
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr & ~TX_UNDERRUN_BIT);
    }

    if(!uac_en && !ts_mp4_en){ //All audio functions are disabled.
        glAudioEnable = FALSE;
        gsAudioPreviewStartEnable = 0;

        dbg_printf(3, "PCAM_USB_AudioStop() End\r\n");
    }

    if(uac_flag)
    {
        PCAM_USB_SetAudioWorkMode(MMPF_AUDIO_WORK_MODE_UAC, MMPF_AUDIO_WORK_STATUS_DISABLE);                                        
        dbg_printf(3, "USB_AUDStop() --> UAC\r\n");
    }
    
    if(ts_mp4_flag)
    {
        PCAM_USB_SetAudioWorkMode(MMPF_AUDIO_WORK_MODE_TS_MP4, MMPF_AUDIO_WORK_STATUS_DISABLE);                                    
        dbg_printf(3, "USB_AUDStop() --> TS-MP4\r\n");
    }
    

//#if (MicSource==MicInPathI2S) && (AUDEXT_DAC==WM8737)
//    glAudioCodecInit = FALSE;  // skip first volume setting after audio on for Windows XP
//#endif

    if(USB_IsPreviewActive() == FALSE) {
        RTNA_DBG_Str3("  ==LED Off==\r\n");
        USB_LEDDisplay(LED_READY, LED_OFF);
    }

    return err ;
}

MMP_USHORT PCAM_USB_SetVolume(pcam_msg_t *msg)
{
  //  AITPS_AUD   pAUD    = AITC_BASE_AUD;
    PCAM_AUDIO_CFG *pcam_audio = (PCAM_AUDIO_CFG *)msg->msg_data;
    MMP_SHORT voldb = pcam_audio->pCamVolume ;
    #if(MicSource == MicInPathAFE)
    MMP_UBYTE dgain=0;
    #endif
    
    //RTNA_DBG_Str3("Vol:[");RTNA_DBG_Short3(voldb);RTNA_DBG_Str3("]\r\n");

	#if(MicSource == MicInPathAFE)
    PCAM_USB_SetGain_UAC2ADC(voldb);
    #endif

    if(!glAudioEnable) {
        return PCAM_ERROR_NONE ;
    }  

    
    if(!pcam_audio->pCamMute) {
#if(MicSource == MicInPathAFE)
		 
         MMPF_Audio_SetADCAnalogGain(gbADCAnalogGain,gbADCBoost);  
         //MMPC_System_WaitMs(1); // 1 ms for smooth ~  

#elif(MicSource == MicInPathI2S)

        ISP_IF_3A_Control(ISP_3A_PAUSE);
    	MMPF_Sensor_3A_SetInterrupt(0);

    #if (AUDEXT_DAC==WM8737)
    {
    	MMP_UBYTE dgain;
        //WM8737 logic, dgain is for APGA
        //the range check should be done before here. 0x8000 will not call here.
        dgain = (MMP_UBYTE) ((MMP_BYTE)((voldb - FIXED_PREAMP) >> 7) + 0xC3);
        if ((voldb == (MMP_SHORT)0x8000) || (voldb == VOL_MIN)) {
            dgain = 0;
        }
		//0xC3 == 0db
        MMPF_WM8737VolumeControl(dgain);
	}   
    #endif

    #if (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778)

//    if(!pcam_audio->pCamMute) {
        MMPF_CX20709VolumeControl((MMP_UBYTE)(voldb>>8));        
//    }

    #endif
    #if (AUDEXT_DAC==WM8973) || (AUDEXT_DAC==WM8750) || (AUDEXT_DAC==WM8960)
		MMPC_AudioExtCodec_SetRecordVolume((MMP_LONG)(voldb));        
	#endif
	#if AUDEXT_DAC==ADC3101
        MMPF_TLV320ADC3101VolumeControl(voldb>>8);
    #endif

	    ISP_IF_3A_Control(ISP_3A_RECOVER);
	    MMPF_Sensor_3A_SetInterrupt(1);

#endif
		
    }
    
    #if(MicSource == MicInPathAFE)
    //RTNA_DBG_Str3("[AGain:");RTNA_DBG_Byte3(pAUD->AFE_ADC_GAIN_CTL.V1.PGA_GAIN);RTNA_DBG_Str3("], ");
    //RTNA_DBG_Str3("[DGain:");RTNA_DBG_Short3(pAUD->AFE_ADC_GAIN_CTL.V1.LR_VOL) ;RTNA_DBG_Str3("], ");
    //RTNA_DBG_Str3("[Boost:");RTNA_DBG_Byte3(pAUD->AFE_ADC_BOOST_CTL ) ;RTNA_DBG_Str3("]\r\n");
    #endif
     return PCAM_ERROR_NONE ;
}

MMP_USHORT PCAM_USB_SetSamplingRate(pcam_msg_t *msg)
{

    AITPS_AUD   pAUD    = AITC_BASE_AUD;
    AITPS_AIC   pAIC = AITC_BASE_AIC;
    PCAM_AUDIO_CFG *pcam_audio = (PCAM_AUDIO_CFG *)msg->msg_data;

    MMP_USHORT audin = I2S_IN ;
    //MMP_UBYTE prio_err,old_prio,new_prio;

	//return;

    RTNA_DBG_Str3("PCAM_USB_SetSamplingRate = ");
    MMPF_DBG_Int(pcam_audio->pCamSampleRate, -6);
    RTNA_DBG_Str3("\r\n");

    //prio_err = MMPF_OS_ChangePrio(20,&old_prio,&new_prio);
	
    if(glAudioEnable) {

	    MMPF_Audio_TimerClose(MMPF_TIMER_2);
        gbAud1stInToken = 0 ;

        //ISP_IF_3A_Control(ISP_3A_PAUSE);
	    //MMPF_Sensor_3A_SetInterrupt(0);

		pCamCtx.audioInPath = PCAM2MMP_Get_AudioInPath(pcam_audio) ;
        // stop first
		MMPF_Audio_SetMux(audin, 0);   	
		RTNA_AIC_IRQ_Dis(pAIC, AIC_SRC_AUD_FIFO);

        pAUD->I2S_CTL = 0;//disable  hck

        {    
		MMP_USHORT  csr;
		csr = UsbReadTxEpCSR(PCCAM_AU_EP_ADDR);
        csr = csr & TXCSR_RW_MASK;
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr | SET_TX_FLUSHFIFO);
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr | SET_TX_FLUSHFIFO);
		csr = UsbReadTxEpCSR(PCCAM_AU_EP_ADDR) ;
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr & ~TX_UNDERRUN_BIT);
    	}
    	
    
		if(pCamCtx.audioInPath==AUDIO_IN_I2S) {
            MMPF_Audio_SetI2SInFormat(1) ; // Set slave

        #if AUDEXT_DAC==WM8737
            MMPF_PowerUpWM8737(pcam_audio->pCamSampleRate) ;
        #endif
        #if (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778)
            MMPF_CX20709_Set_SampleRate(pcam_audio->pCamSampleRate);
        #endif
        #if (AUDEXT_DAC == ADC3101)
            MMPF_PowerUpTLV320ADC3101(pcam_audio->pCamSampleRate) ;
            MMPC_AudioExtCodec_SetSampleRate(pcam_audio->pCamSampleRate);
            //MMPF_OS_Sleep(200);
		#endif
        #if (AUDEXT_DAC==WM8973) || (AUDEXT_DAC==WM8750)
            MMPC_AudioExtCodec_SetSampleRate(pcam_audio->pCamSampleRate) ;
        #endif
	 	}

#if USB_UAC_TO_QUEUE==1
        MMPF_Audio_InitEncoder( ENC_SAMPLES_TIME*((pcam_audio->pCamSampleRate*AUDIN_CHANNEL)/1000) ) ;
#endif
		MMPF_Audio_InitializeEncodeFIFO(audin, /*ENC_SAMPLES_TIME*/AFE_SAMPLES_TIME*((pcam_audio->pCamSampleRate*AUDIN_CHANNEL)/1000));	
        MMPF_InitAudioSetting(audin, pcam_audio->pCamSampleRate);   //initial iis registers        
		
	    if(pCamCtx.audioInPath==AUDIO_IN_I2S) {
        	pAUD->I2S_CTL = (I2S_HCK_CLK_EN);//enable hck
	    }

		MMPF_Audio_SetMux(audin, 1);
	    if(pCamCtx.audioInPath==AUDIO_IN_I2S) {
			RTNA_AIC_IRQ_En(pAIC, AIC_SRC_AUD_FIFO);
        }

		{    
		MMP_USHORT  csr;
		csr = UsbReadTxEpCSR(PCCAM_AU_EP_ADDR);
        csr = csr & TXCSR_RW_MASK;
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr | SET_TX_FLUSHFIFO);
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr | SET_TX_FLUSHFIFO);
		csr = UsbReadTxEpCSR(PCCAM_AU_EP_ADDR) ;
        UsbWriteTxEpCSR(PCCAM_AU_EP_ADDR, csr & ~TX_UNDERRUN_BIT);
    	}

    	//ISP_IF_3A_Control(ISP_3A_RECOVER);
	    //MMPF_Sensor_3A_SetInterrupt(1);

    	MMPF_Audio_TimerOpen(UAC_TIMER_MS_LENGTH, MMPF_TIMER_2);

    }
    
    //prio_err = MMPF_OS_ChangePrio(0,&new_prio,&old_prio);
    
    RTNA_DBG_Str3("PCAM_USB_SetSamplingRate() End..\r\n");
    
    return 0;
}
MMP_USHORT PCAM_USB_SetMute(pcam_msg_t *msg)
{
    //AITPS_AUD   pAUD    = AITC_BASE_AUD;
    PCAM_AUDIO_CFG *pcam_audio = (PCAM_AUDIO_CFG *)msg->msg_data;
    //MMP_SHORT voldb = pcam_audio->pCamVolume ;
    //MMP_UBYTE dgain ;

    RTNA_DBG_Str3("PCAM_USB_SetMute:");RTNA_DBG_Byte3(pcam_audio->pCamMute);RTNA_DBG_Str3("\r\n");
    
    if(!glAudioEnable) {
#if MicSource==MicInPathAFE
//        if(pcam_audio->pCamMute) {
//            gbOrigADCDigitalGain = gbADCDigitalGain ;
//            gbADCDigitalGain = 0;
//        } else {
//            gbADCDigitalGain = gbOrigADCDigitalGain ;
//        }
#endif
        return PCAM_ERROR_NONE ;
    }
    if(pcam_audio->pCamMute) {

#if MicSource==MicInPathAFE
        if(gbADCDigitalGain) {
            gbOrigADCDigitalGain = gbADCDigitalGain ;
        }
        //gbOrigADCAnalogGain = gbADCAnalogGain ;
        //gbOrigADCBoost =  ( pAUD->AFE_ADC_BOOST_CTL & (ADC_L_BOOST_UP_EN | ADC_R_BOOST_UP_EN) ) ? 1 : 0;
        // Set Digital Gain to Zero
        MMPF_Audio_SetADCDigitalGain(0) ; // mute
        // MMPF_Audio_SetADCAnalogGain(0 ,0);// -10dB, no boost
#elif(MicSource == MicInPathI2S)

    #if (AUDEXT_DAC==WM8737)
        MMPF_WM8737VolumeControl(0);        
    #endif
    #if (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778)
        MMPF_CX20709_SetMute(1);        
    #endif
	#if (AUDEXT_DAC==WM8973) || (AUDEXT_DAC==WM8750) || (AUDEXT_DAC==WM8960)
		MMPC_AudioExtCodec_SetMute(MMP_TRUE);        
	#endif
	#if AUDEXT_DAC==ADC3101
        MMPF_TLV320ADC3101_SetMute(1);
    #endif
#endif


    } else {
#if MicSource==MicInPathAFE

        // restore 
        if(gbADCDigitalGain) {
            MMPF_Audio_SetADCDigitalGain(gbADCDigitalGain);
        } else {
            MMPF_Audio_SetADCDigitalGain(gbOrigADCDigitalGain);
        }
        
#elif(MicSource == MicInPathI2S)

    #if (AUDEXT_DAC==WM8737)
    {
        MMP_UBYTE dgain;
        MMP_SHORT voldb = pcam_audio->pCamVolume;
//        if(glAudioCodecInit == TRUE){  // skip first volume setting after audio on for Windows XP
            //WM8737 logic, dgain is for APGA
            //the range check should be done before here. 0x8000 will not call here.
            dgain = (MMP_UBYTE) ((MMP_BYTE)((voldb - FIXED_PREAMP) >> 7) + 0xC3);
            if ((voldb == (MMP_SHORT)0x8000) || (voldb == VOL_MIN)) {
                dgain = 0;
            }

            MMPF_WM8737VolumeControl(dgain);        
//        }
    }
    #endif
    #if (AUDEXT_DAC==CX20709) || (AUDEXT_DAC==CX20778)

        MMPF_CX20709_SetMute(0);        

    #endif
    #if (AUDEXT_DAC==WM8973) || (AUDEXT_DAC==WM8750) || (AUDEXT_DAC==WM8960)
		MMPC_AudioExtCodec_SetMute(MMP_FALSE);        
	#endif
	#if AUDEXT_DAC==ADC3101
        MMPF_TLV320ADC3101_SetMute(0);
    #endif
#endif

    }
    //RTNA_DBG_Str3("Set Chip Orig Digital Gain(dB) : ");
    //RTNA_DBG_Byte3(gbOrigADCDigitalGain);
    //RTNA_DBG_Str3("\r\n");
    //RTNA_DBG_Str3("Set Chip Digital Gain(dB) : ");
    //RTNA_DBG_Byte3(gbADCDigitalGain);
    //RTNA_DBG_Str3("\r\n");

    return PCAM_ERROR_NONE ;
}
#endif  // #if SUPPORT_UAC


#if SUPPORT_ISP_ENGINEERING_MODE_FUNCTION
//MMP_USHORT gammaRoprAddress[33] = {0x7280,0x7281,0x7282,0x7283,0x7284,0x7285,0x7286,0x7287,0x7288,0x7289,0x728A,0x728B,0x728C,0x728D,0x728E,0x728F,0x7290,0x7291,0x7292,0x7293,0x7294,0x7295,0x7296,0x7297,0x7298,0x7299,0x729A,0x729B,0x729C,0x729D,0x729E,0x729F,0x72E0}; 
//MMP_USHORT gammaGoprAddress[33] = {0x72A0,0x72A1,0x72A2,0x72A3,0x72A4,0x72A5,0x72A6,0x72A7,0x72A8,0x72A9,0x72AA,0x72AB,0x72AC,0x72AD,0x72AE,0x72AF,0x72B0,0x72B1,0x72B2,0x72B3,0x72B4,0x72B5,0x72B6,0x72B7,0x72B8,0x72B9,0x72BA,0x72BB,0x72BC,0x72BD,0x72BE,0x72BF,0x72E1}; 
//MMP_USHORT gammaBoprAddress[33] = {0x72C0,0x72C1,0x72C2,0x72C3,0x72C4,0x72C5,0x72C6,0x72C7,0x72C8,0x72C9,0x72CA,0x72CB,0x72CC,0x72CD,0x72CE,0x72CF,0x72D0,0x72D1,0x72D2,0x72D3,0x72D4,0x72D5,0x72D6,0x72D7,0x72D8,0x72D9,0x72DA,0x72DB,0x72DC,0x72DD,0x72DE,0x72DF,0x72E2}; 
MMP_UBYTE gammaVal[ISP_GAMMA_TBL_R_NUM+ISP_GAMMA_TBL_G_NUM+ISP_GAMMA_TBL_B_NUM];
MMP_BOOL bDownloadGAMMATabletoRAM = 0;

MMP_USHORT PCAM_UpdateGAMMAtoRAM(void)
{
	MMP_UBYTE i;
	//Update GAMMA to RAM ============================================

	if(bDownloadGAMMATabletoRAM){
#if (CHIP==VSN_V2)
		for(i=0; i<(ISP_GAMMA_TBL_R_NUM-1); i++) {
			ISP_IF_IQ_SetOpr( ISP_GAMMA_TBL_R_OPR_BASE + i, 1, gammaVal[i]);
			ISP_IF_IQ_SetOpr( ISP_GAMMA_TBL_G_OPR_BASE + i, 1, gammaVal[ISP_GAMMA_TBL_R_NUM+i]);
			ISP_IF_IQ_SetOpr( ISP_GAMMA_TBL_B_OPR_BASE + i, 1, gammaVal[ISP_GAMMA_TBL_R_NUM+ISP_GAMMA_TBL_G_NUM+i]);
		}
		ISP_IF_IQ_SetOpr( ISP_GAMMA_TBL_R_LAST_ADDR, 1, gammaVal[ISP_GAMMA_TBL_R_NUM-1]);
		ISP_IF_IQ_SetOpr( ISP_GAMMA_TBL_G_LAST_ADDR, 1, gammaVal[ISP_GAMMA_TBL_G_NUM-1]);
		ISP_IF_IQ_SetOpr( ISP_GAMMA_TBL_B_LAST_ADDR, 1, gammaVal[ISP_GAMMA_TBL_B_NUM-1]);
#endif //(CHIP==VSN_V2)
		bDownloadGAMMATabletoRAM = 0;
		RTNA_DBG_Str(0, "=== Update ISP GAMMA data to RAM end ===\r\n");
	}
	else{
		//No GAMMA data need update!
	}
    return PCAM_ERROR_NONE ;
}
#endif

extern MMP_UBYTE eu1_get_mmp_result_val[];
#if (CUSTOMER == CCN) || (SUPPORT_CNXT_FW_DOWNLOADING_EEPROM) || (CUSTOMER == LON) || (CUSTOMER == ASU) || (CUSTOMER == PNS)
extern MMP_UBYTE *USBFirmwareBinPtr;
extern MMP_ULONG USBFirmwareBinSize;
#endif
extern MMP_BOOL BurnErr;    //Verify FW Burning
MMP_USHORT PCAM_USB_UpdateFirmware(pcam_msg_t *msg)
{
#if (CUSTOMER == NMG)  
    AITPS_AIC   pAIC = AITC_BASE_AIC;
    AITPS_GPIO  pGPIO = AITC_BASE_GPIO;
#endif
  //  AITPS_GBL   pGBL = AITC_BASE_GBL;
    MMP_USHORT step = *(MMP_USHORT *)msg->msg_data;
    MMP_ERR   err;//0: OK, 1:error

#if 0
    RTNA_DBG_Str( 3,"PCAM_USB_UpdateFirmware:");
    RTNA_DBG_Short(3,step);
    RTNA_DBG_Str(3,"\r\n");
#endif
    switch (step)
    {
    case 0:
        USB_DownloadFWInitialize();
        break;
    case 1:
#if (CUSTOMER == NMG)
        RTNA_AIC_IRQ_Dis(pAIC, AIC_SRC_GPIO);
	    MMPF_PIO_EnableInterrupt(IRHID_PIN, MMP_FALSE, 0x0, NULL);
#endif
        if(gbUVCPara[0] == 0){
            RTNA_DBG_Str( 3,"Old Firmware Package\r\n");
            err = USB_Burning840FW2SFlash();
            if(BurnErr) //Verify FW Burning
                err = 1;
        }
        else if(gbUVCPara[0] == 1){
            RTNA_DBG_Str( 3,"New Firmware Package\r\n");
            //status = USB_BurningROMPackage();
        }
#if (SUPPORT_CNXT_FW_DOWNLOADING_EEPROM)
        else if(gbUVCPara[0] == 3){
        
            RTNA_DBG_Str( 3,"Update CX2070x Firmware\r\n");

            RTNA_DBG_Str(3, "CX2070x FW start address = ");
            RTNA_DBG_Long(3, (MMP_ULONG) USBFirmwareBinPtr);
            RTNA_DBG_Str(3, "\r\n");
            RTNA_DBG_Str(3, "CX2070x Firmware Size = ");
            RTNA_DBG_Long(3, (MMP_ULONG) USBFirmwareBinSize);
            RTNA_DBG_Str(3, "\r\n");

    	#if (MicSource==MicInPathI2S)

        	#if (CUSTOMER == LIT)  
            GPIO_OutputControl(CNX_PWR_EN, TRUE);
        
            //GPIO_OutputControl(CNX_RST, FALSE);
            GPIO_OutputControl(CNX_RST, TRUE);
            MMPF_OS_Sleep(200);
            #endif

        	#if ((CUSTOMER == CCN) && (MODEL == 1)) || ((CUSTOMER == LGT) && (MODEL == 1)) 
            GPIO_OutputControl(CNX_PWR_EN, TRUE);
            GPIO_OutputControl(CAM_EN, TRUE);  // for LED control
        
            //GPIO_OutputControl(CNX_RST, FALSE);
            GPIO_OutputControl(CNX_RST, TRUE);
            MMPF_OS_Sleep(200);
            #endif
            
            #if ((CUSTOMER == ANW) && (AUDEXT_DAC == CX20709))
            GPIO_OutputControl(CNX_RST, TRUE);
            MMPF_OS_Sleep(200);
            #endif
        
        #endif

	    err = MMPF_CX2070xDownload();

    	#if (CUSTOMER == LIT) 
        GPIO_OutputControl(CNX_RST, FALSE);
        GPIO_OutputControl(CNX_PWR_EN, FALSE);
        #endif

        #if ((CUSTOMER == ANW) && (AUDEXT_DAC == CX20709))
        GPIO_OutputControl(CNX_RST, FALSE);
        MMPF_OS_Sleep(100);
        GPIO_OutputControl(CNX_RST, TRUE);
        MMPF_OS_Sleep(1000);
        #endif

    	    #if ((CUSTOMER == CCN) && (MODEL == 1)) || ((CUSTOMER == LGT) && (MODEL == 1)) 
            GPIO_OutputControl(CNX_RST, FALSE);
            GPIO_OutputControl(CNX_PWR_EN, FALSE);
            if(USB_IsPreviewActive() == FALSE) {  // check if video is alive or not for LED control.
                GPIO_OutputControl(CAM_EN, FALSE);
            }
            #endif

            ISP_IF_3A_Control(ISP_3A_RECOVER);
        	MMPF_Sensor_3A_SetInterrupt(1);
            USBFirmwareBinSize = 0;
#if (CUSTOMER != LIT)
            USB_LEDDisplay(LED_READY, LED_OFF);
#endif
            RTNA_DBG_Str(0, "=== MMPF_CX2070xDownload() successfully ===\r\n");
            
        }
#endif

#if (CUSTOMER == CCN) || (CUSTOMER == LON)
        else if(gbUVCPara[0]==4){//update custom table
            //MMP_UBYTE *temp = (MMP_UBYTE *) (0x01400000L);
            RTNA_DBG_Str( 3,"Update Custom Table\r\n");

            RTNA_DBG_Str(3, "Custom Table start address = ");
            RTNA_DBG_Long(3, (MMP_ULONG) USBFirmwareBinPtr);
            RTNA_DBG_Str(3, "\r\n");
            RTNA_DBG_Str(3, "Custom Table Size = ");
            RTNA_DBG_Long(3, (MMP_ULONG) USBFirmwareBinSize);
            RTNA_DBG_Str(3, "\r\n");
            //Burning840PCCAMFirmwareImage(CUSTOMER_INIT_FLASH_SIZE);
            //RTNA_DBG_Long(3, *(MMP_ULONG*)USBFirmwareBinPtr);           
            //MMPF_SIF_Init();
            MMPF_SF_SetTmpAddr((MMP_ULONG)SIF_BUFFER_START);
            MMPF_SF_InitialInterface();
            if (MMPF_SF_Reset()) {
#if EN_DBGLOG_FOR_FLASH
                RTNA_DBG_Str(0, "\r\nSIF init error !!\r\n");
#endif
            }
            MMPF_SIF_WriteData(CUSTOMER_INIT_FLASH_ADDR,(MMP_ULONG)USBFirmwareBinPtr,USBFirmwareBinSize);

            ISP_IF_3A_Control(ISP_3A_RECOVER);
        	MMPF_Sensor_3A_SetInterrupt(1);
            USBFirmwareBinSize = 0;
#if (CUSTOMER != LIT)
            USB_LEDDisplay(LED_READY, LED_OFF);
#endif
            RTNA_DBG_Str(3, " Finish. \r\n");         	
        }
#endif
#if	(CUSTOMER == PNS)
		else if(gbUVCPara[0]==4){	//Write user 256Byte data
            dbg_printf(3, "Update Customer Table\r\nAddr = %08X, size = %X\r\n", USBFirmwareBinPtr, USBFirmwareBinSize);
            
            DBG_S(2, "Update flash data ");
			if(USBFirmwareBinSize > CUSTOMER_DATA_SIZE_IN_FLASH){
				DBG_S(2, "size error!!!\r\n");
				err = 1;
			}
			else{
            	MMPF_SF_InitialInterface();
            	MMPF_SIF_WriteData(MAX_FLASH_SIZE - CUSTOMER_DATA_SIZE_IN_FLASH,(MMP_ULONG)USBFirmwareBinPtr,USBFirmwareBinSize);
            	DBG_S(2, "Done.\r\n");
            	if (MMPF_SF_GetTotalSize() != MAX_FLASH_SIZE) {
            	    dbg_printf(3, "\r\n[Warning] MAX_FLASH_SIZE %X SD size\r\n", MAX_FLASH_SIZE, MMPF_SF_GetTotalSize());
            	}
            	err = 0;
            }
		}
#endif
#if (CUSTOMER == ASU)
#if (SUPPORT_ISP_ENGINEERING_MODE_FUNCTION==1||SUPPORT_ISP_CALIBRATION_FUNCTION==1)
		else if(gbUVCPara[0]==5)/*cmd3*/{//update user CALI table
            MMP_UBYTE ISP_CALI_TAG [XU_CMD_HEADER_TAG_CHECK_SIZE] = {'I','S', 'P', '_', 'C', 'A', 'L', 'I'};
			XU_CALI_TABLE *AIT_Cali_Data;
#if _DBGMSG_
			volatile MMP_UBYTE *REG_BASE_B = (volatile MMP_UBYTE *) (0x80000000);
			MMP_USHORT nGetRegValue = 0;
#endif
			extern MMP_BOOL bDownloadTabletoRAM;

#if _DBGMSG_
		    nGetRegValue = (REG_BASE_B[0x707F]<<8) | REG_BASE_B[0x707E];
		    RTNA_DBG_Str(3, "P4, LS cx = ");
		    RTNA_DBG_Short(3, nGetRegValue);
		    RTNA_DBG_Str(3, "\r\n");
#endif
            dbg_printf(3, "Update Shading Table :Start\r\nTable size = %d\r\n", USBFirmwareBinSize);

			AIT_Cali_Data = (XU_CALI_TABLE*)USBFirmwareBinPtr;

#if _DBGMSG_
            RTNA_DBG_Str(3, "hs = ");
            RTNA_DBG_Long(3, AIT_Cali_Data->pHeader.header_size);
            RTNA_DBG_Str(3, "\r\n");
            RTNA_DBG_Str(3, "ds = ");
            RTNA_DBG_Long(3, AIT_Cali_Data->pHeader.data_size);
            RTNA_DBG_Str(3, "\r\n");
#endif

			RTNA_DBG_Str(0, "=== Write ISP Calibration data begin ===\r\n");
            
            if( memcmp(AIT_Cali_Data->pHeader.tag, ISP_CALI_TAG, XU_CMD_HEADER_TAG_CHECK_SIZE) != 0){
                RTNA_DBG_Str(0, "ISP file header is wrong!!!\r\n");
                err = 1;
            }
            else{
				if(gbUVCPara[1]==1){//cmd[2]
					//write Shading to RAM =============================
#if _DBGMSG_
		            RTNA_DBG_Str(3, "color_temp = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pHeader.color_temp);
		            RTNA_DBG_Str(3, ", lux = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pHeader.lux);
		            RTNA_DBG_Str(3, "\r\n");
		            RTNA_DBG_Str(3, ", sensor = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pHeader.sensor_id);
		            RTNA_DBG_Str(3, "\r\n");
#endif

					//AWB ============================================
#if _DBGMSG_
		            RTNA_DBG_Str(3, "awbr = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pAWBTbl.gainr);
		            RTNA_DBG_Str(3, ", awbgr = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pAWBTbl.gaingr);
		            RTNA_DBG_Str(3, ", awbgb = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pAWBTbl.gaingb);
		            RTNA_DBG_Str(3, ", awbb = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pAWBTbl.gainb);
		            RTNA_DBG_Str(3, "\r\n");
#endif

					ISP_IF_CALI_SetAWB( 0,
										AIT_Cali_Data->pAWBTbl.gainr, 
										AIT_Cali_Data->pAWBTbl.gaingr, 
										AIT_Cali_Data->pAWBTbl.gaingb, 
										AIT_Cali_Data->pAWBTbl.gainb,
										AIT_Cali_Data->pHeader.color_temp, 
										AIT_Cali_Data->pHeader.lux);

					//LS =============================================
#if _DBGMSG_
		            RTNA_DBG_Str(3, "bx = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pLSTbl.basex);
		            RTNA_DBG_Str(3, ", by = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pLSTbl.basey);
		            RTNA_DBG_Str(3, ", ox = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pLSTbl.offsetx);
		            RTNA_DBG_Str(3, ", oy = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pLSTbl.offsety);
		            RTNA_DBG_Str(3, ", cx = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pLSTbl.centerx);
		            RTNA_DBG_Str(3, ", cy = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pLSTbl.centery);
		            RTNA_DBG_Str(3, ", rx = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pLSTbl.ratex);
		            RTNA_DBG_Str(3, ", ry = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pLSTbl.ratey);
		            RTNA_DBG_Str(3, ", tblr = ");
		            RTNA_DBG_Short(3, *(MMP_USHORT *)(AIT_Cali_Data->pLSTbl.tblr));
		            RTNA_DBG_Str(3, ", tblg = ");
		            RTNA_DBG_Short(3, *(MMP_USHORT *)(AIT_Cali_Data->pLSTbl.tblg));
		            RTNA_DBG_Str(3, ", tblb = ");
		            RTNA_DBG_Short(3, *(MMP_USHORT *)(AIT_Cali_Data->pLSTbl.tblb));
		            RTNA_DBG_Str(3, "\r\n");

				    nGetRegValue = (REG_BASE_B[0x707F]<<8) | REG_BASE_B[0x707E];
				    RTNA_DBG_Str(3, "P5, LS cx = ");
				    RTNA_DBG_Short(3, nGetRegValue);
		            RTNA_DBG_Str(3, "\r\n");
#endif

					ISP_IF_CALI_SetLS(	0,
										AIT_Cali_Data->pLSTbl.basex, AIT_Cali_Data->pLSTbl.basey,
										AIT_Cali_Data->pLSTbl.centerx, AIT_Cali_Data->pLSTbl.centery,
										AIT_Cali_Data->pLSTbl.offsetx, AIT_Cali_Data->pLSTbl.offsety,
										AIT_Cali_Data->pLSTbl.ratex, AIT_Cali_Data->pLSTbl.ratey,
										(MMP_USHORT *)(AIT_Cali_Data->pLSTbl.tblr), 
										(MMP_USHORT *)(AIT_Cali_Data->pLSTbl.tblg), 
										(MMP_USHORT *)(AIT_Cali_Data->pLSTbl.tblb),
										AIT_Cali_Data->pHeader.color_temp, 
										AIT_Cali_Data->pHeader.lux);

					//CS =============================================
#if _DBGMSG_
		            RTNA_DBG_Str(3, "bx = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pCSTbl.basex);
		            RTNA_DBG_Str(3, ", by = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pCSTbl.basey);
		            RTNA_DBG_Str(3, ", ox = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pCSTbl.offsetx);
		            RTNA_DBG_Str(3, ", oy = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pCSTbl.offsety);
		            RTNA_DBG_Str(3, ", cx = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pCSTbl.centerx);
		            RTNA_DBG_Str(3, ", cy = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pCSTbl.centery);
		            RTNA_DBG_Str(3, ", scale = ");
		            RTNA_DBG_Short(3, AIT_Cali_Data->pCSTbl.scale);
		            RTNA_DBG_Str(3, ", px = ");
		            RTNA_DBG_Short(3, *(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.posx));
		            RTNA_DBG_Str(3, ", py = ");
		            RTNA_DBG_Short(3, *(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.posy));
		            RTNA_DBG_Str(3, ", tblr = ");
		            RTNA_DBG_Short(3, *(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.tblr));
		            RTNA_DBG_Str(3, ", tblg = ");
		            RTNA_DBG_Short(3, *(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.tblg));
		            RTNA_DBG_Str(3, ", tblb = ");
		            RTNA_DBG_Short(3, *(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.tblb));
		            RTNA_DBG_Str(3, "\r\n");
#endif

#if 0
					//wait ISP next version fix shading, then turn on
					ISP_IF_CALI_SetCS(	0,
										AIT_Cali_Data->pCSTbl.basex, AIT_Cali_Data->pCSTbl.basey,
										AIT_Cali_Data->pCSTbl.centerx, AIT_Cali_Data->pCSTbl.centery,
										AIT_Cali_Data->pCSTbl.offsetx, AIT_Cali_Data->pCSTbl.offsety,
										AIT_Cali_Data->pCSTbl.scale,
										(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.posx), 
										(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.posy),
										(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.tblr), 
										(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.tblg), 
										(MMP_USHORT *)(AIT_Cali_Data->pCSTbl.tblb),
										AIT_Cali_Data->pHeader.color_temp, 
										AIT_Cali_Data->pHeader.lux);
#endif

					ISP_IF_CALI_SetAWBMode(ISP_CALI_MODE_MANUAL_0);
	                ISP_IF_CALI_SetLSMode(ISP_CALI_MODE_MANUAL_0);
					//wait ISP next version fix shading, then turn on
//	                ISP_IF_CALI_SetCSMode(ISP_CALI_MODE_MANUAL_0);

#if _DBGMSG_
				    nGetRegValue = (REG_BASE_B[0x707F]<<8) | REG_BASE_B[0x707E];
				    RTNA_DBG_Str(3, "P7, LS cx = ");
				    RTNA_DBG_Short(3, nGetRegValue);
				    RTNA_DBG_Str(3, "\r\n");
#endif
	                err = 0;
					RTNA_DBG_Str(0, "=== Write ISP Calibration data to RAM end ===\r\n");

		            if(bDownloadTabletoRAM==1) {
		            	ISP_IF_3A_Control(ISP_3A_RECOVER);
		            	MMPF_Sensor_3A_SetInterrupt(1);
		            	MMPF_VIF_EnableOutput(1);

		            	MMPF_Sensor_CheckFrameStart(1);
#if _DBGMSG_
					    nGetRegValue = (REG_BASE_B[0x707F]<<8) | REG_BASE_B[0x707E];
					    RTNA_DBG_Str(3, "P8, LS cx = ");
					    RTNA_DBG_Short(3, nGetRegValue);
					    RTNA_DBG_Str(3, "\r\n");
#endif
		            	bDownloadTabletoRAM = 0;
						RTNA_DBG_Str(0, "\r\nResume VIF!!\r\n");
		            }
				}
				else if(gbUVCPara[1]==3){//cmd[2]
				    //Update calibration table in the flash from XU command data
				    err = USB_AppendCaliData(AIT_Cali_Data, gbUVCPara[2]/*cmd[4]*/);
				}
	            else{
	                dbg_printf(3, "!Incorrect cmd[2] = %02X\r\n", gbUVCPara[1]);
	                err = 1;
	            }

            }
            RTNA_DBG_Str(3, "Update CALI Table: End \r\n");
		}
#if (IQ_TABLE_LOAD_FROM_FLASH)
#if 0
        //temp solution for older IQ tool, w/o IQ header
		else if(gbUVCPara[0]==6||gbUVCPara[0]==7){//update user IQ table
			XuCmdIspIqGammaTable *AIT_IqGAMMA_Data;
			//u_int i=0;//debug
			u_int flash_addr;

            AIT_IqGAMMA_Data = (XuCmdIspIqGammaTable*)USBFirmwareBinPtr;

			RTNA_DBG_Str(0, "=== Write ISP IQ/GAMMA data begin ===\r\n");

			//write IQ to Serial Flash =========================

			RTNA_DBG_Str( 3,"Update IQ Table : Start\r\n");
            RTNA_DBG_Str(3, "Table Size = ");
            RTNA_DBG_Long(3, (MMP_ULONG) USBFirmwareBinSize);
            RTNA_DBG_Str(3, "\r\n");
            MMPF_SF_SetTmpAddr((MMP_ULONG)SIF_BUFFER_START);
            MMPF_SF_InitialInterface();
            if (MMPF_SF_Reset()) {
                RTNA_DBG_Str(0, "\r\nSIF init error !!\r\n");
            }

            if(gbUVCPara[0]==6)
            {
	            RTNA_DBG_Str(0, "MAIN SENSOR\r\n");
            	flash_addr = IQ_TABLE_ADDR_IN_FLASH;//MAIN_SENSOR
            }else if(gbUVCPara[0]==7)
            {
	            RTNA_DBG_Str(0, "SUB SENSOR\r\n");
            	flash_addr = IQ_TABLE2_ADDR_IN_FLASH;//SUB_SENSOR
            }
            
            MMPF_SIF_WriteData(flash_addr,(MMP_ULONG)USBFirmwareBinPtr,USBFirmwareBinSize);
            #if 0//debug
            for(i=0;i<0x10;i++)
            {
	            *((MMP_ULONG *)(USBFirmwareBinPtr+i*4))=0;
	            RTNA_DBG_Str(3, "i, data = ");
	            RTNA_DBG_Long(3, i);
	            RTNA_DBG_Long(3, *(MMP_ULONG *)(USBFirmwareBinPtr+i*4));
	            RTNA_DBG_Str(3, "\r\n");
            }
            
            MMPF_SIF_ReadDataEx(flash_addr,(MMP_ULONG)USBFirmwareBinPtr, 0x40);
            for(i=0;i<0x10;i++)
            {
	            RTNA_DBG_Str(3, "new i, data = ");
	            RTNA_DBG_Long(3, i);
	            RTNA_DBG_Long(3, *(MMP_ULONG *)(USBFirmwareBinPtr+i*4));
	            RTNA_DBG_Str(3, "\r\n");
            }
            #endif
            RTNA_DBG_Str(3, "Update IQ Table: End \r\n");

            err = 0;
			//RTNA_DBG_Str(0, "=== Write ISP IQ/GAMMA data to Serial Flash end ===\r\n");
        }
#else
		else if(gbUVCPara[0]==6){//update user IQ table
            MMP_UBYTE	isp_iqtb_header[XU_CMD_HEADER_TAG_CHECK_SIZE] = {'I','S', 'P', '_', 'I', 'Q', 'T', 'B'};
            MMP_UBYTE	isp_gama_header[XU_CMD_HEADER_TAG_CHECK_SIZE] = {'I','S', 'P', '_', 'G', 'A', 'M', 'A'};
			XU_IQ_GAMMA_TABLE *AIT_IqGAMMA_Data;
			MMP_ULONG	Offset=0;

			extern MMP_BOOL bDownloadTabletoRAM;

			RTNA_DBG_Str( 3,"Update IQ : Start\r\n");
            RTNA_DBG_Str(3, "Table Size = ");
            RTNA_DBG_Long(3, (MMP_ULONG) USBFirmwareBinSize);
            RTNA_DBG_Str(3, "\r\n");

            AIT_IqGAMMA_Data = (XU_IQ_GAMMA_TABLE*)USBFirmwareBinPtr;

#if _DBGMSG_
            RTNA_DBG_Str(3, "hs = ");
            RTNA_DBG_Long(3, AIT_IqGAMMA_Data->pHeader.header_size);
            RTNA_DBG_Str(3, "\r\n");
            RTNA_DBG_Str(3, "ds = ");
            RTNA_DBG_Long(3, AIT_IqGAMMA_Data->pHeader.data_size);
            RTNA_DBG_Str(3, "\r\n");
            if(USBFirmwareBinSize < (XU_CMD_HEADER_TAG_CHECK_SIZE+AIT_IqGAMMA_Data->pHeader.header_size+AIT_IqGAMMA_Data->pHeader.data_size)){
                dbg_printf(0, "!Incorrect Download size:0x%X < data size:0x%X\r\n", USBFirmwareBinSize, (XU_CMD_HEADER_TAG_CHECK_SIZE+AIT_IqGAMMA_Data->pHeader.header_size+AIT_IqGAMMA_Data->pHeader.data_size));
            }
#endif

			RTNA_DBG_Str(0, "=== Write ISP IQ/GAMMA data begin ===\r\n");
            
            if( memcmp(AIT_IqGAMMA_Data->pHeader.tag, isp_gama_header, XU_CMD_HEADER_TAG_CHECK_SIZE) == 0){

				if(gbUVCPara[1]==1){
					//write GAMMA to RAM ===============================

					for(Offset=0; Offset<ISP_GAMMA_TBL_R_NUM; Offset++) {
						gammaVal[Offset] = *(MMP_UBYTE *)(AIT_IqGAMMA_Data->pGAMMATbl.tblr[Offset]);
						gammaVal[ISP_GAMMA_TBL_R_NUM+Offset] = *(MMP_UBYTE *)(AIT_IqGAMMA_Data->pGAMMATbl.tblg[Offset]);
						gammaVal[ISP_GAMMA_TBL_G_NUM+Offset] = *(MMP_UBYTE *)(AIT_IqGAMMA_Data->pGAMMATbl.tblb[Offset]);
					}
					bDownloadGAMMATabletoRAM = 1;

	                err = 0;
					RTNA_DBG_Str(0, "=== copy ISP GAMMA data to RAM end ===\r\n");

		            if(bDownloadTabletoRAM==1) {
		            	ISP_IF_3A_Control(ISP_3A_RECOVER);
		            	MMPF_Sensor_3A_SetInterrupt(1);
		            	MMPF_VIF_EnableOutput(1);
		            	bDownloadTabletoRAM = 0;
						RTNA_DBG_Str(0, "\r\nResume VIF!!\r\n");
					}
				}
				else if(gbUVCPara[1]==3){
					//write GAMMA to Serial Flash ======================
					RTNA_DBG_Str(0, "=== !Need implement ===\r\n");
	                err = 1;
					//RTNA_DBG_Str(0, "=== Write ISP GAMMA data to Serial Flash end ===\r\n");
				}
	            else{
	                RTNA_DBG_Str(0, "!Incorrect, cmd[2] = ");
		            RTNA_DBG_Byte(3, gbUVCPara[1]);
		            RTNA_DBG_Str(3, "\r\n");
	                err = 1;
	            }
			}
            if( memcmp(AIT_IqGAMMA_Data->pHeader.tag, isp_iqtb_header, XU_CMD_HEADER_TAG_CHECK_SIZE) == 0){

				if(gbUVCPara[1]==1){
					//write IQ to RAM ==================================
					RTNA_DBG_Str(0, "!Not Support update IQ to RAM ===\r\n");
	                err = 1;
				}
				else if(gbUVCPara[1]==3){
					//write IQ to Serial Flash =========================

					//u_int i=0;//debug
					u_int flash_addr;
					RTNA_DBG_Str( 3,"Update IQ Table : Start\r\n");
		            RTNA_DBG_Str(3, "Table Size = ");
		            RTNA_DBG_Long(3, (MMP_ULONG) USBFirmwareBinSize);
		            RTNA_DBG_Str(3, "\r\n");
		            if (USB_ResetFlash()) {
		                RTNA_DBG_Str(0, "\r\nSIF init error !!\r\n");
		            }

		            if(AIT_IqGAMMA_Data->pHeader.sensor_id==0){
		            	RTNA_DBG_Str(0, "MAIN SENSOR\r\n");
		            	flash_addr = IQ_TABLE_ADDR_IN_FLASH;//MAIN_SENSOR
		            }else if(AIT_IqGAMMA_Data->pHeader.sensor_id==1){
		            	RTNA_DBG_Str(0, "SUB SENSOR\r\n");
		            	flash_addr = IQ_TABLE2_ADDR_IN_FLASH;//SUB_SENSOR
		            }else{
		            	dbg_printf(0, "!Incorrect sensor id:%d\r\n", AIT_IqGAMMA_Data->pHeader.sensor_id);
	                	err = 1;
	                	break;
		            }
		            
		            MMPF_SIF_WriteData(flash_addr,(MMP_ULONG)USBFirmwareBinPtr,USBFirmwareBinSize);
		            #if 0//debug
		            for(i=0;i<0x10;i++)
		            {
			            *((MMP_ULONG *)(USBFirmwareBinPtr+i*4))=0;
			            RTNA_DBG_Str(3, "i, data = ");
			            RTNA_DBG_Long(3, i);
			            RTNA_DBG_Long(3, *(MMP_ULONG *)(USBFirmwareBinPtr+i*4));
			            RTNA_DBG_Str(3, "\r\n");
		            }
		            
		            MMPF_SIF_ReadDataEx(flash_addr,(MMP_ULONG)USBFirmwareBinPtr, 0x40);
		            for(i=0;i<0x10;i++)
		            {
			            RTNA_DBG_Str(3, "new i, data = ");
			            RTNA_DBG_Long(3, i);
			            RTNA_DBG_Long(3, *(MMP_ULONG *)(USBFirmwareBinPtr+i*4));
			            RTNA_DBG_Str(3, "\r\n");
		            }
		            #endif
		            RTNA_DBG_Str(3, "Update IQ Table: End \r\n");

#if (CUSTOMER != LIT)
                    USB_LEDDisplay(LED_READY, LED_OFF); //turn off after download complete
#endif

	                err = 0;
					//RTNA_DBG_Str(0, "=== Write ISP IQ/GAMMA data to Serial Flash end ===\r\n");
				}
	            else{
	                RTNA_DBG_Str(0, "!Incorrect, cmd[2] = ");
		            RTNA_DBG_Byte(3, gbUVCPara[1]);
		            RTNA_DBG_Str(3, "\r\n");
	                err = 1;
	            }
			}
			else{

                RTNA_DBG_Str(0, "ISP file header is wrong!!!\r\n");
                err = 1;
            }
            RTNA_DBG_Str(3, "Update IQ/GAMMA Table: End \r\n");
		}
#endif
#endif
#endif
#endif

        if(err == 0){
            eu1_get_mmp_result_val[0] = XU_MMP_CMD_OK;  // No Error (0x00)
            MMPF_OS_Sleep(500);
            if(gbUVCPara[0] == 0){
#if (CHIP_VER == VER_B) // reset AIT to reboot ROM           
		    MMPF_SYS_ResetSystem(0x0);		
#endif
            }
        }
        else{
            eu1_get_mmp_result_val[0] = XU_MMP_BURNING_ERROR;  // Burning FW Error (0x82)
        }
        break;    
    case 2:
        return PCAM_USB_FIRMWARE_ERR ;
    }   
    return PCAM_ERROR_NONE ;
    
}

MMP_USHORT PCAM_USB_TaskAlive(pcam_msg_t *msg)
{

#if UART_DBG_EN==1
    //RTNA_DBG_Str(3,"[PCAM] : Alive\r\n");
#endif    
#if HEARTBEAT_LED_EN==1
    MMP_USHORT heartbeat = *(MMP_USHORT *)msg->msg_data;
    USB_LEDDisplay(TEST_PIN1,heartbeat);
#endif    
    return PCAM_ERROR_NONE ;
}


MMP_USHORT PCAM_USB_EraseFlash(MMP_UBYTE mode, MMP_ULONG addr)
{
    AITPS_GBL pGBL = AITC_BASE_GBL;
	AITPS_SIF pSIF = AITC_BASE_SIF;
    MMP_ULONG clock;

#if 0
    RTNA_DBG_Str( 3,"PCAM_USB_EraseFlash:");
    RTNA_DBG_Byte(3,mode);
    RTNA_DBG_Str( 3," : ");
    RTNA_DBG_Long(3,addr);
    RTNA_DBG_Str(3,"\r\n");
#endif
    
    switch(mode) {
    case 1:  // Chip Erase
        break;
    case 2:  // Sector Erase
        
        clock = pGBL->GBL_CLK_DIS1;
        pGBL->GBL_CLK_DIS0 &= ~GBL_CLK_BS_SPI_DIS;
   	    pSIF->SIF_CLK_DIV = 4;
            
		MMPF_SF_EraseSector(addr);
		
		pGBL->GBL_CLK_DIS1 = clock;
    
        break;    
    default:
        return PCAM_USB_FIRMWARE_ERR ;
    }   
    return PCAM_ERROR_NONE ;
    
}

//------------------------------------------------------------------------------
//  Function    : RawImageCapture
//------------------------------------------------------------------------------
MMP_USHORT PCAM_USB_TakeRawPicture(pcam_msg_t *msg)
{
#if CAPTURE_BAYER_RAW_ENABLE
	AITPS_GBL   pGBL    = AITC_BASE_GBL;
    MMP_ULONG ulRawStoreAddr = *(MMP_ULONG *)msg->msg_data;

    pGBL->GBL_CLK_DIS1 &= (~GBL_CLK_RAW_DIS);
    	
    RTNA_DBG_Str3("RawStoreAddr:");	RTNA_DBG_Long3(ulRawStoreAddr);RTNA_DBG_Str3("\r\n");
    
    MMPF_RAWPROC_SetRawBuffer(0, ulRawStoreAddr); 
    MMPF_RAWPROC_SetCaptureStoreAddr();   
//   	MMPF_Display_SetWinActive(gPreviewWinID[0], MMP_FALSE);

	#if (CHIP == P_V2)||(CHIP == VSN_V2)
    // do software reset over jpeg and image control block
//	pGBL->GBL_RST_SW_CTL |= GBL_MODULE_JPG | GBL_MODULE_IBC | GBL_MODULE_VI | GBL_MODULE_SCAL;
//    RTNA_WAIT_CYCLE(100);
//	pGBL->GBL_RST_SW_CTL &= ~(GBL_MODULE_JPG | GBL_MODULE_IBC | GBL_MODULE_VI | GBL_MODULE_SCAL);
	#endif
	
    RTNA_DBG_Str(0, "MMPF_DSC_Calibrate1-0\r\n");
    /*
    Note: MMPF_Display_StopPreview have stopped VIF, so
          we can switch path here.
    */
    
    MMPF_RAWPROC_Reset();
    MMPF_RAWPROC_EnableRawPath(MMP_TRUE);
    MMPF_RAWPROC_SetCaptureStoreAddr();
  
    
    RTNA_DBG_Str(0, "MMPF_DSC_Calibrate1-0-1\r\n");

	
	// *((AIT_REG_B*)0x8000040A) = *((AIT_REG_B*)0x8000040A) | (1 << 7);
    MMPF_VIF_EnableInputInterface(MMP_TRUE);
	
	
	RTNA_DBG_Str(0, "MMPF_DSC_Calibrate1-0-2\r\n");
    MMPF_Sensor_CheckFrameStart(1);
	RTNA_DBG_Str(0, "MMPF_DSC_Calibrate1-0-3\r\n");
	
    
    MMPF_RAWPROC_StoreSensorData(MMP_TRUE,MMP_FALSE);
    
    MMPF_Sensor_CheckFrameStart(2);  // waiting for raw process done

    MMPF_VIF_EnableInputInterface(MMP_FALSE);    
	// *((AIT_REG_B*)0x8000040A) = *((AIT_REG_B*)0x8000040A) & ~(1 << 7);

	#if (CHIP == P_V2)||(CHIP == VSN_V2)
    // do software reset over jpeg and image control block
//	pGBL->GBL_RST_SW_CTL |= GBL_MODULE_JPG | GBL_MODULE_IBC | GBL_MODULE_VI | GBL_MODULE_SCAL;
//    RTNA_WAIT_CYCLE(100);
//	pGBL->GBL_RST_SW_CTL &= ~(GBL_MODULE_JPG | GBL_MODULE_IBC | GBL_MODULE_VI | GBL_MODULE_SCAL);
	#endif	 


    MMPF_RAWPROC_EnableRawPath(MMP_FALSE);

    pGBL->GBL_CLK_DIS1 |= GBL_CLK_RAW_DIS;
#endif

	return MMP_ERR_NONE;    
}

MMP_USHORT PCAM_USB_Set_FPS(MMP_SHORT fps) 
{
static MMP_SHORT gsCurFPS ;

 //   VAR_W(3,fps);
    
    if(fps==0) {
        ISP_IF_AE_SetFPS(0);
        return 0;
    }
    
    if(fps > 0) {
        gsCurFPS = fps ;
    }
 //   VAR_W(3,gsCurFPS);
    
    ISP_IF_AE_SetFPS(gsCurFPS);
    return MMP_ERR_NONE;
}

#if SUPPORT_UAC
void PCAM_USB_AudioSetMode(pcam_msg_t *msg)
{
    MMP_UBYTE mode = *(MMP_UBYTE *)msg->msg_data;
#if AUDEXT_DAC==CX20709 
	switch( mode )
	{
		case 0: //Audio Mode 0
		    break;
		case 1: //Audio Mode 1
		    break;
		case 2: //Audio Mode 2
		    break;
		case 3: //Audio Mode 3
		    break;
		case 4: //Audio Mode 4 for Geortek calibrate on mp line.
		    break;
		case 5: // Bypass CX20709 audio processing
            if(glAudioEnable) {
                MMPF_CX20709_Set_Bypass_Mode(1);  
            }
            gbAudioProcBypassFlag = 1;
		    break;
		case 6: // Enable CX20709 audio processing
            if(glAudioEnable) {
                MMPF_CX20709_Set_Bypass_Mode(0);  
            }
            gbAudioProcBypassFlag = 0;
		    break;
		default:
			RTNA_DBG_Str(3,"Audio mode setting error \r\n");
		    break;
	}
#endif	
	gbAudioMode = mode ;
	

}
#endif

static MMP_USHORT PCAM2MMP_Get_Quality(PCAM_USB_INFO *pcam_info)
{
    MMP_USHORT q = VIDRECD_QUALITY_HIGH ;
    switch(pcam_info->pCamVideoQuality) {
    case PCAM_USB_HIGH_Q:
        q = VIDRECD_QUALITY_HIGH ;
        break ;
    case PCAM_USB_NORMAL_Q:
        q = VIDRECD_QUALITY_MID ;
        break ;
    case PCAM_USB_LOW_Q:
        q = VIDRECD_QUALITY_LOW ;
        break ;
    default:
        q = VIDRECD_QUALITY_HIGH ; //pcam_info->pCamVideoQuality ;
        break ;    
    }
    return q ;
}



static MMP_USHORT PCAM2MMP_Get_Resolution(PCAM_USB_INFO *pcam_info)
{
    return pcam_info->pCamVideoRes;
}

static MMPS_3GPRECD_VIDEO_FORMAT PCAM2MMP_Get_VideoFormat(PCAM_USB_INFO *pcam_info)
{
    MMPS_3GPRECD_VIDEO_FORMAT fmt = MMPS_3GPRECD_VIDEO_FORMAT_H264 ;
    switch(pcam_info->pCamVideoFormat) {
    case PCAM_USB_VIDEO_FORMAT_H263:
        fmt = MMPS_3GPRECD_VIDEO_FORMAT_H263 ;
        break ;
    case PCAM_USB_VIDEO_FORMAT_MP4V:
        fmt = MMPS_3GPRECD_VIDEO_FORMAT_MP4V ;
        break ;
    case PCAM_USB_VIDEO_FORMAT_H264:
        fmt = MMPS_3GPRECD_VIDEO_FORMAT_H264 ;
        break ;
    case PCAM_USB_VIDEO_FORMAT_MJPEG:
        fmt = MMPS_3GPRECD_VIDEO_FORMAT_MJPEG ;
        break ;
    case PCAM_USB_VIDEO_FORMAT_YUV422:
        fmt = MMPS_3GPRECD_VIDEO_FORMAT_YUV422 ;
        break ;
    case PCAM_USB_VIDEO_FORMAT_YUV420:
        fmt = MMPS_3GPRECD_VIDEO_FORMAT_YUV420 ;
        break ;
    case PCAM_USB_VIDEO_FORMAT_RAW:
		fmt = MMPS_3GPRECD_VIDEO_FORMAT_RAW;
		break;        
    }
    return fmt ;
}

#if SUPPORT_UAC
static MMPS_3GPRECD_AUDIO_FORMAT PCAM2MMP_Get_AudioFormat(PCAM_USB_INFO *pcam_info)
{
    MMPS_3GPRECD_AUDIO_FORMAT fmt = MMPS_3GPRECD_AUDIO_FORMAT_AAC ;
    switch(pcam_info->pCamAudioFormat) {
    case PCAM_USB_AUDIO_FORMAT_AAC:
        fmt = MMPS_3GPRECD_AUDIO_FORMAT_AAC;
        break;
    case PCAM_USB_AUDIO_FORMAT_AMR:
        fmt = MMPS_3GPRECD_AUDIO_FORMAT_AMR;
        break;        
    }
    return fmt ;
}
#endif

static MMP_USHORT PCAM2MMP_Get_DebandMode(PCAM_USB_INFO *pcam_info)
{
    MMP_USHORT deband = SENSOR_DSC_DEBAND_60HZ ;
    if(pcam_info->pCamDebandMode==PCAM_USB_DEBAND_50HZ) {
        	deband = SENSOR_DSC_DEBAND_50HZ;
    }
    if(pcam_info->pCamDebandMode==PCAM_USB_DEBAND_AUTO) {
        	deband = SENSOR_DSC_DEBAND_AUTO;
    }
    if(pcam_info->pCamDebandMode==PCAM_USB_DEBAND_AUTO_LIMITEXPO) {
        	deband = SENSOR_DSC_DEBAND_AUTO_LIMITEXPO;
    }
    if(pcam_info->pCamDebandMode==PCAM_USB_DEBAND_50HZ_LIMITEXPO) {
        	deband = SENSOR_DSC_DEBAND_50HZ_LIMITEXPO;
    }
    if(pcam_info->pCamDebandMode==PCAM_USB_DEBAND_60HZ_LIMITEXPO) {
        	deband = SENSOR_DSC_DEBAND_60HZ_LIMITEXPO;
    }
    return deband ;
}

#if SUPPORT_UAC
static MMP_USHORT PCAM2MMP_Get_AudioInPath(PCAM_AUDIO_CFG *pcam_audio)
{
    MMP_USHORT audin = AUDIO_IN_AFE_DIFF ;
    switch(pcam_audio->pCamAudioInPath) {
    case PCAM_AUDIO_IN_I2S:
        audin = AUDIO_IN_I2S ; 
        break; 
    case PCAM_AUDIO_AFE_SING:
        audin = AUDIO_IN_AFE_SING ; 
        break; 
    case PCAM_AUDIO_AFE_DIFF:
        audin = AUDIO_IN_AFE_DIFF ; 
        break; 
    case PCAM_AUDIO_AFE_DIFF2SING:
        audin = AUDIO_IN_AFE_DIFF2SING ; 
        break; 
    }
    return audin ;
}

static MMPF_AUDIO_LINEIN_CHANNEL PCAM2MMP_Get_AudioInChannel(PCAM_AUDIO_CFG *pcam_audio)
{
    MMPF_AUDIO_LINEIN_CHANNEL channel = MMPF_AUDIO_LINEIN_DUAL ;
    switch(pcam_audio->pCamAudioChannel) {
    case PCAM_AUDIO_LINEIN_DUAL:
        channel = MMPF_AUDIO_LINEIN_DUAL ;
        break; 
    case PCAM_AUDIO_LINEIN_R:
        channel = MMPF_AUDIO_LINEIN_R ;
        break; 
    case PCAM_AUDIO_LINEIN_L:
        channel = MMPF_AUDIO_LINEIN_L ;
        break; 
    }
    return channel ;
}
#endif

static MMP_SHORT PCAM2MMP_Normalize_Value(MMP_USHORT val)
{
//    MMP_SHORT n_val = (MMP_SHORT)(( ( 200.0 * val ) / 255 ) - 100 ) ;
    MMP_SHORT n_val = (MMP_SHORT)(( ( 200 * val ) / 255 ) - 100 ) ;//Truman@121115 Float is not needed
   // VAR_W(0,n_val) ;
    return n_val ;   
}


#if 0//(CUSTOMER != ASU)
//static MMP_USHORT PCAM2MMP_Normalize_EV(MMP_USHORT val)
static MMP_SHORT PCAM2MMP_Normalize_EV(MMP_SHORT val)
{
//  MMP_USHORT n_val = (MMP_USHORT)(( ( 20.0 * val ) / 255 )  ) ;
    //VAR_W(0,n_val) ;
   	
   	MMP_SHORT n_val = (MMP_SHORT)(( ( 20 * val ) / 255 )  ) ;//Truman@121115 Float is not needed
	
	n_val = (n_val - 10) * 25;
    return n_val ;   
    
}
#endif
// UVC range : 0~ 255
// AIT Gain range : 64~511
static MMP_USHORT PCAM2MMP_Normalize_Gain(MMP_USHORT val)
{
    return  (MMP_USHORT)(val * ( 511 - 64 ) / 255 + 64) ;   
   
}

// -180 ~ 180 -> -100 ~ 100
static MMP_SHORT PCAM2MMP_Normalize_HUE(MMP_SHORT val)
{
    //MMP_SHORT n_val = (MMP_SHORT)(( ( 200.0 * val ) / 360 ) ) ;
    MMP_SHORT n_val = (MMP_SHORT)(( ( 200 * val ) / 360 ) ) ;//Truman@121115 Float is not needed
   // VAR_W(0,n_val) ;
    return n_val ;   
}